summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2014-08-11 17:47:01 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2014-08-11 17:47:01 +0100
commiteb4d1c0be04d768afe4947f75724a130b2bd2256 (patch)
tree0126c3db55c4905b6ddd36b33c8fc4b791b80054 /src
parent2acad458c10bee63c168a7b16fc26f1b1e448bbd (diff)
parent0f8ba377cb458ec0c5de18a450189e701f710a1e (diff)
Do not sleep for tiny periods, or hang trying to sleep for zero. Bug 1426
Diffstat (limited to 'src')
-rw-r--r--src/src/exim.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/src/src/exim.c b/src/src/exim.c
index 517b5435e..51daa5576 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -267,6 +267,10 @@ will wait for ever, so we panic in this instance. (There was a case of this
when a bug in a function that calls milliwait() caused it to pass invalid data.
That's when I added the check. :-)
+We assume it to be not worth sleeping for under 100us; this value will
+require revisiting as hardware advances. This avoids the issue of
+a zero-valued timer setting meaning "never fire".
+
Argument: an itimerval structure containing the interval
Returns: nothing
*/
@@ -276,6 +280,9 @@ milliwait(struct itimerval *itval)
{
sigset_t sigmask;
sigset_t old_sigmask;
+
+if (itval->it_value.tv_usec < 100 && itval->it_value.tv_sec == 0)
+ return;
(void)sigemptyset(&sigmask); /* Empty mask */
(void)sigaddset(&sigmask, SIGALRM); /* Add SIGALRM */
(void)sigprocmask(SIG_BLOCK, &sigmask, &old_sigmask); /* Block SIGALRM */