mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
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:
parent
8dccfbce4c
commit
8fa4d5c43f
1 changed files with 11 additions and 3 deletions
|
|
@ -37,6 +37,7 @@ struct AvahiWatch {
|
||||||
AvahiWatchEvent events;
|
AvahiWatchEvent events;
|
||||||
AvahiWatchCallback callback;
|
AvahiWatchCallback callback;
|
||||||
void *userdata;
|
void *userdata;
|
||||||
|
unsigned int dispatching;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AvahiTimeout {
|
struct AvahiTimeout {
|
||||||
|
|
@ -65,9 +66,14 @@ static void watch_callback(void *data, int fd, uint32_t mask)
|
||||||
{
|
{
|
||||||
AvahiWatch *w = data;
|
AvahiWatch *w = data;
|
||||||
|
|
||||||
|
w->dispatching += 1;
|
||||||
|
|
||||||
w->events = from_pw_events(mask);
|
w->events = from_pw_events(mask);
|
||||||
w->callback(w, fd, w->events, w->userdata);
|
w->callback(w, fd, w->events, w->userdata);
|
||||||
w->events = 0;
|
w->events = 0;
|
||||||
|
|
||||||
|
if (--w->dispatching == 0 && !w->source)
|
||||||
|
free(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
static AvahiWatch* watch_new(const AvahiPoll *api, int fd, AvahiWatchEvent event,
|
static AvahiWatch* watch_new(const AvahiPoll *api, int fd, AvahiWatchEvent event,
|
||||||
|
|
@ -103,9 +109,11 @@ static AvahiWatchEvent watch_get_events(AvahiWatch *w)
|
||||||
|
|
||||||
static void watch_free(AvahiWatch *w)
|
static void watch_free(AvahiWatch *w)
|
||||||
{
|
{
|
||||||
struct impl *impl = w->impl;
|
pw_loop_destroy_source(w->impl->loop, w->source);
|
||||||
pw_loop_destroy_source(impl->loop, w->source);
|
w->source = NULL;
|
||||||
free(w);
|
|
||||||
|
if (!w->dispatching)
|
||||||
|
free(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void timeout_callback(void *data, uint64_t expirations)
|
static void timeout_callback(void *data, uint64_t expirations)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue