connection: rework interrupted system call implementation
authorDaniel Mack <daniel@zonque.org>
Tue, 28 Oct 2014 11:47:22 +0000 (12:47 +0100)
committerDaniel Mack <daniel@zonque.org>
Tue, 28 Oct 2014 11:47:22 +0000 (12:47 +0100)
commitca7879fedb6a695af925ea06d10da4046660f01e
treec75bd0172ed6688facf0c82f89ad548d2a33c07e
parent7570f87dd231dc537ca4b698ee305d57196704d1
connection: rework interrupted system call implementation

Calls that end up in wait_event_interruptible_timeout() are subject
to be interrupted if the userspace task receives a signal. In such
cases, the function will return -ERESTARTSYS, and in case a signal
handler was installed with SA_RESTART, the syscall would be
automatically restarted.

However, in case of KDBUS_CMD_MSG_SEND, however, we have to avoid
sending the same message again in that case, which is why we
decided to return -EINPROGRESS before, and let userspace call into
a special ioctl to catch up on the 2nd half of the SEND syscall.

However, it turns out there's a much simpler solution to that:

 * If a system call is interrupted, we set .interrupted = true in
   the reply tracker object, so it will be cleaned up by the
   connection worker.

 * When KDBUS_CMD_MSG_SEND is calles in a synchronous fashion,
   try to find a reply tracking object in the destination connection.
   If it exists, and is marked as .interrupted == true, catch up on
   it, and go back to wait_event_interruptible_timeout() right away.

That way, we can explicitly support SA_RESTART now, and as timeouts
are absolute, a restarted syscall does the right thing.

Signed-off-by: Daniel Mack <daniel@zonque.org>
connection.c