chiark / gitweb /
sd-event: "when exiting no signal event are pending" is a wrong assertion (#5271)
authorFranck Bui <fbui@suse.com>
Wed, 8 Feb 2017 19:56:22 +0000 (20:56 +0100)
committerSven Eden <yamakuzure@gmx.net>
Mon, 19 Jun 2017 07:40:51 +0000 (09:40 +0200)
The code make the following assertion: when freeing a event loop object
(usually it's done after exiting from the main event loop), no signal events
are still queued and are pending.

This assertion can be found in event_unmask_signal_data() with
"assert(!d->current);" assertion.

It appears that this assertion can be wrong at least in a specific case
described below.

Consider the following example which is inspired from udev: a process defines 3
source events: 2 are created by sd_event_add_signal() and 1 is created by
sd_event_add_post().

 1. the process receives the 2 signals consecutively so that signal 'A' source
     event is queued and pending. Consequently the post source event is also
     queued and pending. This is done by sd_event_wait().

 2. The callback for signal 'A' is called by sd_event_dispatch().

 3. The next call to sd_event_wait() will queue signal 'B' source event.

 4. The callback for the post source event is called and calls sd_event_exit().

 5. the event loop is exited.

 6. freeing the event loop object will lead to the assertion failure in
     event_unmask_signal_data().

This patch simply removes this assertion as it doesn't seem to be a
bug if the signal data still reference a signal source at this point.

(cherry picked from commit 4470860388e12a5dda1d65773e411a349221a3e9)

src/libelogind/sd-event/sd-event.c

index c3673f08a65a0b1d8d8ff7b214fa442ff1630c03..cfd5a55457758a7ceadd8ab9d0299af6f7920926 100644 (file)
@@ -732,7 +732,6 @@ static void event_unmask_signal_data(sd_event *e, struct signal_data *d, int sig
 
                 /* If all the mask is all-zero we can get rid of the structure */
                 hashmap_remove(e->signal_data, &d->priority);
 
                 /* If all the mask is all-zero we can get rid of the structure */
                 hashmap_remove(e->signal_data, &d->priority);
-                assert(!d->current);
                 safe_close(d->fd);
                 free(d);
                 return;
                 safe_close(d->fd);
                 free(d);
                 return;