Mir

Merge lp:~aacid/mir/eintr_dispatch_loop into lp:mir

Proposed by Albert Astals Cid on 2015-11-18
Status: Merged
Merged at revision: 3120
Proposed branch: lp:~aacid/mir/eintr_dispatch_loop
Merge into: lp:mir
Diff against target: 12 lines (+2/-0)
1 file modified
src/common/dispatch/threaded_dispatcher.cpp (+2/-0)
To merge this branch: bzr merge lp:~aacid/mir/eintr_dispatch_loop
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing on 2015-11-20
Alan Griffiths Approve on 2015-11-19
Chris Halse Rogers Approve on 2015-11-18
Kevin DuBois (community) Approve on 2015-11-18
Alberto Aguirre 2015-11-18 Approve on 2015-11-18
Review via email: mp+277847@code.launchpad.net

Commit Message

Do not throw exception on EINTR when poll()ing

To post a comment you must log in.
Alberto Aguirre (albaguirre) wrote :

Oh yeah we used to have this with the single thread dispatcher.

And we have a test for this but it's disabled.

review: Approve
Kevin DuBois (kdub) wrote :

> Oh yeah we used to have this with the single thread dispatcher.
>
> And we have a test for this but it's disabled.

is there a bug about the disabled test? lgtm otherwise

review: Approve
Chris Halse Rogers (raof) wrote :

Wait - how did you manage to get an EINTR in the dispatch thread?

We *should* be blocking all signals to that thread. SIGSTOP and SIGKILL can't be blocked, but SIGKILL will immediately end the process so that's not the problem.

We *do* send SIGSTOP to various things, but poll should *not* return EINTR after a SIGSTOP/SIGCONT pair. epoll() (erroneously) does, but poll() is not documented as suffering from that bug.

Oooh! Unless something is registering a SIGCONT handler. Stupid signal behaviour!

Quoth the signal (7) manpage:
   Interruption of system calls and library functions by stop signals
       On Linux, even in the absence of signal handlers, certain blocking interfaces can fail with the
       error EINTR after the process is stopped by one of the stop signals and then resumed via SIG‐
       CONT. This behavior is not sanctioned by POSIX.1, and doesn't occur on other systems.

       The Linux interfaces that display this behavior are:

           * "Input" socket interfaces, when a timeout (SO_RCVTIMEO) has been set on the socket using
             setsockopt(2): accept(2), recv(2), recvfrom(2), recvmmsg(2) (also with a non-NULL timeout
             argument), and recvmsg(2).

           * "Output" socket interfaces, when a timeout (SO_RCVTIMEO) has been set on the socket using
             setsockopt(2): connect(2), send(2), sendto(2), and sendmsg(2), if a send timeout (SO_SND‐
             TIMEO) has been set.

           * epoll_wait(2), epoll_pwait(2).

           * semop(2), semtimedop(2).

           * sigtimedwait(2), sigwaitinfo(2).

           * read(2) from an inotify(7) file descriptor.

           * Linux 2.6.21 and earlier: futex(2) FUTEX_WAIT, sem_timedwait(3), sem_wait(3).

           * Linux 2.6.8 and earlier: msgrcv(2), msgsnd(2).

           * Linux 2.4 and earlier: nanosleep(2).

review: Approve
Alan Griffiths (alan-griffiths) wrote :

Thanks Chris, I did wonder.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/common/dispatch/threaded_dispatcher.cpp'
2--- src/common/dispatch/threaded_dispatcher.cpp 2015-06-17 05:20:42 +0000
3+++ src/common/dispatch/threaded_dispatcher.cpp 2015-11-18 14:59:20 +0000
4@@ -202,6 +202,8 @@
5 {
6 if (poll(&waiter, 1, -1) < 0)
7 {
8+ if (errno == EINTR)
9+ continue;
10 BOOST_THROW_EXCEPTION((std::system_error{errno,
11 std::system_category(),
12 "Failed to wait for event"}));

Subscribers

People subscribed via source and target branches