Merge pull request #163 from vibe-d/fix_interrupt_behavior

Causes the event loop to exit on Posix when being interrupted by a signal
This commit is contained in:
Sönke Ludwig 2020-11-26 10:53:11 +01:00 committed by GitHub
commit 92ac3f454e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 43 additions and 3 deletions

View file

@ -85,6 +85,12 @@ interface EventDriverCore {
in the event queue. The function will return after either the specified in the event queue. The function will return after either the specified
timeout has elapsed, or once the event queue has been fully emptied. timeout has elapsed, or once the event queue has been fully emptied.
On implementations that support it, the function will treat
interruptions by POSIX signals as if an event was received and will
cause it to return. However, note that it is generally recommended to
use `EventDriverSignals` instead of raw signal handlers in order to
avoid their pitfalls as far as possible.
Params: Params:
timeout = Maximum amount of time to wait for an event. A duration of timeout = Maximum amount of time to wait for an event. A duration of
zero will cause the function to only process pending events. A zero will cause the function to only process pending events. A

View file

@ -336,6 +336,13 @@ package class PosixEventLoop {
protected abstract void dispose(); protected abstract void dispose();
/** Waits for and processes a single batch of events.
Returns:
Returns `false` if no event was received before the timeout expired
and `true` if either an event was received, or if the wait was
interrupted by an error or signal.
*/
protected abstract bool doProcessEvents(Duration dur); protected abstract bool doProcessEvents(Duration dur);
/// Registers the FD for general notification reception. /// Registers the FD for general notification reception.

View file

@ -57,7 +57,16 @@ final class EpollEventLoop : PosixEventLoop {
if (evt.events & EPOLLOUT) notify!(EventType.write)(fd); if (evt.events & EPOLLOUT) notify!(EventType.write)(fd);
} }
return true; return true;
} else return false; } else {
// NOTE: In particular, EINTR needs to cause true to be returned
// here, so that user code has a chance to handle any effects
// of the signal handler before waiting again.
//
// Other errors are very likely to to reoccur for the next
// loop iteration, so there is no value in attempting to
// wait again.
return ret < 0;
}
} }
override void dispose() override void dispose()

View file

@ -85,7 +85,16 @@ abstract class KqueueEventLoopBase : PosixEventLoop {
// EV_SIGNAL, EV_TIMEOUT // EV_SIGNAL, EV_TIMEOUT
} }
return true; return true;
} else return false; } else {
// NOTE: In particular, EINTR needs to cause true to be returned
// here, so that user code has a chance to handle any effects
// of the signal handler before waiting again.
//
// Other errors are very likely to to reoccur for the next
// loop iteration, so there is no value in attempting to
// wait again.
return ret < 0;
}
} }
override void dispose() override void dispose()

View file

@ -65,7 +65,16 @@ final class SelectEventLoop : PosixEventLoop {
notify!(EventType.status)(fd); notify!(EventType.status)(fd);
}); });
return true; return true;
} else return false; } else {
// NOTE: In particular, EINTR needs to cause true to be returned
// here, so that user code has a chance to handle any effects
// of the signal handler before waiting again.
//
// Other errors are very likely to to reoccur for the next
// loop iteration, so there is no value in attempting to
// wait again.
return ret < 0;
}
} }
override void dispose() override void dispose()