context: handle context errors

When the context is in error it might be unreffed. Make sure we don't
ever unref the core from the callback because that is not allowed.
Instead, add a defered to the mainloop to clean up later.
This commit is contained in:
Wim Taymans 2019-03-14 13:23:20 +01:00
parent cb7b25277b
commit 49c99f8dee
3 changed files with 65 additions and 4 deletions

View file

@ -23,6 +23,7 @@
#include <pipewire/loop.h>
#include <pulse/mainloop.h>
#include <pulse/xmalloc.h>
#include "internal.h"
@ -376,3 +377,49 @@ void pa_mainloop_set_poll_func(pa_mainloop *m, pa_poll_func poll_func, void *use
{
pw_log_warn("Not Implemented");
}
struct once_info {
void (*callback)(pa_mainloop_api*m, void *userdata);
void *userdata;
};
static void once_callback(pa_mainloop_api *m, pa_defer_event *e, void *userdata) {
struct once_info *i = userdata;
pa_assert(m);
pa_assert(i);
pa_assert(i->callback);
i->callback(m, i->userdata);
pa_assert(m->defer_free);
m->defer_free(e);
}
static void free_callback(pa_mainloop_api *m, pa_defer_event *e, void *userdata) {
struct once_info *i = userdata;
pa_assert(m);
pa_assert(i);
pa_xfree(i);
}
void pa_mainloop_api_once(pa_mainloop_api* m, void (*callback)(pa_mainloop_api *m, void *userdata), void *userdata) {
struct once_info *i;
pa_defer_event *e;
pa_assert(m);
pa_assert(callback);
pa_init_i18n();
i = pa_xnew(struct once_info, 1);
i->callback = callback;
i->userdata = userdata;
pa_assert(m->defer_new);
pa_assert_se(e = m->defer_new(m, once_callback, i));
m->defer_set_destroy(e, free_callback);
}