mirror of
https://gitlab.freedesktop.org/plymouth/plymouth.git
synced 2026-05-07 18:58:01 +02:00
[event-loop] Don't crash by running removed timeouts
We used to run and remove timeouts in a loop. This breaks the case where the dispatched timeout handler removes the timeout itself. We fix it by making timeout handling a two pass thing. First we find which handlers need to be dispatched, and move them to their own list. Then we run through the new list and dispatch the handlers.
This commit is contained in:
parent
d5948e5a91
commit
79baa323e6
1 changed files with 21 additions and 2 deletions
|
|
@ -1123,6 +1123,7 @@ ply_event_loop_disconnect_source (ply_event_loop_t *loop,
|
|||
static void
|
||||
ply_event_loop_handle_timeouts (ply_event_loop_t *loop)
|
||||
{
|
||||
ply_list_t *watches_to_dispatch;
|
||||
ply_list_node_t *node;
|
||||
double now;
|
||||
|
||||
|
|
@ -1130,6 +1131,8 @@ ply_event_loop_handle_timeouts (ply_event_loop_t *loop)
|
|||
|
||||
now = ply_get_timestamp ();
|
||||
node = ply_list_get_first_node (loop->timeout_watches);
|
||||
|
||||
watches_to_dispatch = ply_list_new ();
|
||||
loop->wakeup_time = PLY_EVENT_LOOP_NO_TIMED_WAKEUP;
|
||||
while (node != NULL)
|
||||
{
|
||||
|
|
@ -1142,8 +1145,7 @@ ply_event_loop_handle_timeouts (ply_event_loop_t *loop)
|
|||
if (watch->timeout <= now)
|
||||
{
|
||||
assert (watch->handler != NULL);
|
||||
watch->handler (watch->user_data, loop);
|
||||
free (watch);
|
||||
ply_list_append_data (watches_to_dispatch, watch);
|
||||
ply_list_remove_node (loop->timeout_watches, node);
|
||||
}
|
||||
else {
|
||||
|
|
@ -1156,6 +1158,23 @@ ply_event_loop_handle_timeouts (ply_event_loop_t *loop)
|
|||
node = next_node;
|
||||
}
|
||||
|
||||
node = ply_list_get_first_node (watches_to_dispatch);
|
||||
while (node != NULL)
|
||||
{
|
||||
ply_list_node_t *next_node;
|
||||
ply_event_loop_timeout_watch_t *watch;
|
||||
|
||||
watch = (ply_event_loop_timeout_watch_t *) ply_list_node_get_data (node);
|
||||
next_node = ply_list_get_next_node (loop->timeout_watches, node);
|
||||
|
||||
watch->handler (watch->user_data, loop);
|
||||
free (watch);
|
||||
|
||||
node = next_node;
|
||||
}
|
||||
|
||||
ply_list_free (watches_to_dispatch);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue