sched: fix main loop to allow timeout handlers modify fd set or quit

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.
This commit is contained in:
Miroslav Lichvar 2014-04-10 11:42:47 +02:00
parent ff31702f74
commit 5cb7e6c9c3

11
sched.c
View file

@ -569,13 +569,13 @@ SCH_MainLoop(void)
assert(initialised); assert(initialised);
while (!need_to_exit) { 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 and fill now with current raw time */
dispatch_timeouts(&now); dispatch_timeouts(&now);
/* The timeout handlers may request quit */
if (need_to_exit)
break;
/* Check whether there is a timeout and set it up */ /* Check whether there is a timeout and set it up */
if (n_timer_queue_entries > 0) { if (n_timer_queue_entries > 0) {
@ -591,6 +591,9 @@ SCH_MainLoop(void)
timeout set, this is clearly ridiculous, so stop the run */ timeout set, this is clearly ridiculous, so stop the run */
assert(ptv || n_read_fds); 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); status = select(one_highest_fd, &rd, NULL, NULL, ptv);
errsv = errno; errsv = errno;