mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-11 21:34:53 -04:00
Double-check next timeout when adding events
When resuming the system from a suspended state, the ev_timeout field of a scheduled timer event may be in the past. This leads to unexpected behavior when scheduling a short-duration timer event immediately after returning from suspension, because the new event does not land on top of the timeout minheap and so the event loop (blocked on a possibly long-duration timeout) is not notified. This patch checks for this condition and, if it obtains, notifies the event loop.
This commit is contained in:
parent
13676535c8
commit
9443868d55
10
event.c
10
event.c
@ -2378,12 +2378,18 @@ event_add_nolock_(struct event *ev, const struct timeval *tv,
|
|||||||
common_timeout_schedule(ctl, &now, ev);
|
common_timeout_schedule(ctl, &now, ev);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
struct event* top = NULL;
|
||||||
/* See if the earliest timeout is now earlier than it
|
/* See if the earliest timeout is now earlier than it
|
||||||
* was before: if so, we will need to tell the main
|
* was before: if so, we will need to tell the main
|
||||||
* thread to wake up earlier than it would
|
* thread to wake up earlier than it would otherwise.
|
||||||
* otherwise. */
|
* We double check the timeout of the top element to
|
||||||
|
* handle time distortions due to system suspension.
|
||||||
|
*/
|
||||||
if (min_heap_elt_is_top_(ev))
|
if (min_heap_elt_is_top_(ev))
|
||||||
notify = 1;
|
notify = 1;
|
||||||
|
else if ((top = min_heap_top_(&base->timeheap)) != NULL &&
|
||||||
|
evutil_timercmp(&top->ev_timeout, &now, <))
|
||||||
|
notify = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user