From 07d5ead61791b015da1d53b569ddb22bf0f5d433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Wed, 25 Nov 2020 23:30:38 +0100 Subject: [PATCH] Causes the event loop to exit on Posix when being interrupted by a signal. Previously, the loop logic would simply retry the wait until the given timeout was actually reached (or an event got received), which could be forever. This change makes sure that after an interrupt the higher level code will get a chance to run to possibly handle the effects of the signal. This is a fix for vibe-d/vibe-core#205. --- source/eventcore/drivers/posix/epoll.d | 11 ++++++++++- source/eventcore/drivers/posix/kqueue.d | 11 ++++++++++- source/eventcore/drivers/posix/select.d | 11 ++++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/source/eventcore/drivers/posix/epoll.d b/source/eventcore/drivers/posix/epoll.d index b6a5767..1abb020 100644 --- a/source/eventcore/drivers/posix/epoll.d +++ b/source/eventcore/drivers/posix/epoll.d @@ -57,7 +57,16 @@ final class EpollEventLoop : PosixEventLoop { if (evt.events & EPOLLOUT) notify!(EventType.write)(fd); } 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() diff --git a/source/eventcore/drivers/posix/kqueue.d b/source/eventcore/drivers/posix/kqueue.d index 3692e83..800f4b9 100644 --- a/source/eventcore/drivers/posix/kqueue.d +++ b/source/eventcore/drivers/posix/kqueue.d @@ -85,7 +85,16 @@ abstract class KqueueEventLoopBase : PosixEventLoop { // EV_SIGNAL, EV_TIMEOUT } 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() diff --git a/source/eventcore/drivers/posix/select.d b/source/eventcore/drivers/posix/select.d index dabc491..60a8380 100644 --- a/source/eventcore/drivers/posix/select.d +++ b/source/eventcore/drivers/posix/select.d @@ -65,7 +65,16 @@ final class SelectEventLoop : PosixEventLoop { notify!(EventType.status)(fd); }); 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()