mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-14 06:59:57 -05:00
stream: remove and check callbacks safely
Clear the callbacks from the processing thread to avoid races. Check the callbacks in the processing thread before calling them, we just need to check if there are functions, we checked the method when installing the function. Fixes #3251
This commit is contained in:
parent
8d62bb1e97
commit
784f003068
2 changed files with 29 additions and 9 deletions
|
|
@ -969,10 +969,10 @@ static void call_process(struct filter *impl)
|
|||
{
|
||||
pw_log_trace_fp("%p: call process", impl);
|
||||
if (SPA_FLAG_IS_SET(impl->flags, PW_FILTER_FLAG_RT_PROCESS)) {
|
||||
spa_callbacks_call_fast(&impl->rt_callbacks, struct pw_filter_events,
|
||||
process, 0, impl->rt.position);
|
||||
}
|
||||
else {
|
||||
if (impl->rt_callbacks.funcs)
|
||||
spa_callbacks_call_fast(&impl->rt_callbacks, struct pw_filter_events,
|
||||
process, 0, impl->rt.position);
|
||||
} else {
|
||||
pw_loop_invoke(impl->main_loop,
|
||||
do_call_process, 1, NULL, 0, false, impl);
|
||||
}
|
||||
|
|
@ -1436,10 +1436,19 @@ void pw_filter_destroy(struct pw_filter *filter)
|
|||
free(impl);
|
||||
}
|
||||
|
||||
static int
|
||||
do_remove_callbacks(struct spa_loop *loop,
|
||||
bool async, uint32_t seq, const void *data, size_t size, void *user_data)
|
||||
{
|
||||
struct filter *impl = user_data;
|
||||
spa_zero(impl->rt_callbacks);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hook_removed(struct spa_hook *hook)
|
||||
{
|
||||
struct filter *impl = hook->priv;
|
||||
spa_zero(impl->rt_callbacks);
|
||||
pw_loop_invoke(impl->data_loop, do_remove_callbacks, 1, NULL, 0, true, impl);
|
||||
hook->priv = NULL;
|
||||
hook->removed = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -426,11 +426,13 @@ static inline void call_process(struct stream *impl)
|
|||
pw_log_trace_fp("%p: call process rt:%u", impl, impl->process_rt);
|
||||
if (impl->direction == SPA_DIRECTION_OUTPUT && update_requested(impl) <= 0)
|
||||
return;
|
||||
if (impl->process_rt)
|
||||
spa_callbacks_call_fast(&impl->rt_callbacks, struct pw_stream_events, process, 0);
|
||||
else
|
||||
if (impl->process_rt) {
|
||||
if (impl->rt_callbacks.funcs)
|
||||
spa_callbacks_call_fast(&impl->rt_callbacks, struct pw_stream_events, process, 0);
|
||||
} else {
|
||||
pw_loop_invoke(impl->main_loop,
|
||||
do_call_process, 1, NULL, 0, false, impl);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -1693,10 +1695,19 @@ void pw_stream_destroy(struct pw_stream *stream)
|
|||
free(impl);
|
||||
}
|
||||
|
||||
static int
|
||||
do_remove_callbacks(struct spa_loop *loop,
|
||||
bool async, uint32_t seq, const void *data, size_t size, void *user_data)
|
||||
{
|
||||
struct stream *impl = user_data;
|
||||
spa_zero(impl->rt_callbacks);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hook_removed(struct spa_hook *hook)
|
||||
{
|
||||
struct stream *impl = hook->priv;
|
||||
spa_zero(impl->rt_callbacks);
|
||||
pw_loop_invoke(impl->data_loop, do_remove_callbacks, 1, NULL, 0, true, impl);
|
||||
hook->priv = NULL;
|
||||
hook->removed = NULL;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue