]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
sched: fix main loop to allow timeout handlers modify fd set or quit
authorMiroslav Lichvar <mlichvar@redhat.com>
Thu, 10 Apr 2014 09:42:47 +0000 (11:42 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 10 Apr 2014 09:47:43 +0000 (11:47 +0200)
With special reference update modes, the timeout handlers may add or
remove file descriptors from the read fd set, so it needs to be copied
for select() call after they are dispatched. Also, they can now request
quit, so the exit flag needs to be checked before select() to avoid
hanging.

sched.c

diff --git a/sched.c b/sched.c
index 148f231a5af63101636f5c4f4096a24c17f09b47..8c547a100bb190ec961efb8f0d551dbb9b50e936 100644 (file)
--- a/sched.c
+++ b/sched.c
@@ -569,13 +569,13 @@ SCH_MainLoop(void)
   assert(initialised);
 
   while (!need_to_exit) {
-
-    /* Copy current set of read file descriptors */
-    memcpy((void *) &rd, (void *) &read_fds, sizeof(fd_set));
-    
     /* Dispatch timeouts and fill now with current raw time */
     dispatch_timeouts(&now);
     
+    /* The timeout handlers may request quit */
+    if (need_to_exit)
+      break;
+
     /* Check whether there is a timeout and set it up */
     if (n_timer_queue_entries > 0) {
 
@@ -591,6 +591,9 @@ SCH_MainLoop(void)
        timeout set, this is clearly ridiculous, so stop the run */
     assert(ptv || n_read_fds);
 
+    /* Copy current set of read file descriptors */
+    memcpy((void *) &rd, (void *) &read_fds, sizeof(fd_set));
+
     status = select(one_highest_fd, &rd, NULL, NULL, ptv);
     errsv = errno;