pipewire: module-zeroconf-discover: handle when AvahiWatch is freed while dispatching

When a particular AvahiWatch is being dispatched, it cannot
be freed because `watch_callback()` accesses it after
the callback.

Introduce a member (`dispatching`) to coordinate
the deferred freeing in that case.

The timeouts are not affected because the `AvahiTimeout`
object is not accessed after the callback is called.
This commit is contained in:
Barnabás Pőcze 2022-03-07 17:45:23 +01:00
parent 8dccfbce4c
commit 8fa4d5c43f

View file

@ -37,6 +37,7 @@ struct AvahiWatch {
AvahiWatchEvent events;
AvahiWatchCallback callback;
void *userdata;
unsigned int dispatching;
};
struct AvahiTimeout {
@ -65,9 +66,14 @@ static void watch_callback(void *data, int fd, uint32_t mask)
{
AvahiWatch *w = data;
w->dispatching += 1;
w->events = from_pw_events(mask);
w->callback(w, fd, w->events, w->userdata);
w->events = 0;
if (--w->dispatching == 0 && !w->source)
free(w);
}
static AvahiWatch* watch_new(const AvahiPoll *api, int fd, AvahiWatchEvent event,
@ -103,8 +109,10 @@ static AvahiWatchEvent watch_get_events(AvahiWatch *w)
static void watch_free(AvahiWatch *w)
{
struct impl *impl = w->impl;
pw_loop_destroy_source(impl->loop, w->source);
pw_loop_destroy_source(w->impl->loop, w->source);
w->source = NULL;
if (!w->dispatching)
free(w);
}