mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-07-02 00:06:09 -04:00
audioconvert: sync filter-graphs out of data loop before forced rebuild
A forced setup_filter_graphs() deactivates and re-instantiates every graph, which frees and recreates the underlying plugin handles (node_cleanup sets node->hndl[i] = NULL before re-instantiating). This was done on a graph that was still referenced by the RT data-loop snapshot (filter_graph[]), so the RT thread could run a graph whose handles were NULL mid-rebuild, leading to a NULL handle dereference in the filter-graph process path. Mirror the safe ordering already used by load_filter_graph()/clean_filter_handles(): before reconfiguring, mark the graphs not-setup and sync_filter_graph() so the data loop drops them from filter_graph[] under the loop lock. They are republished by the sync that follows setup. The cheap snapshot swap is done under the lock; the heavy re-instantiation stays off the RT path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
10b339bbf8
commit
f174b4e688
1 changed files with 16 additions and 0 deletions
|
|
@ -1368,6 +1368,8 @@ static int ensure_tmp(struct impl *this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void sync_filter_graph(struct impl *impl);
|
||||||
|
|
||||||
static int setup_filter_graphs(struct impl *impl, bool force)
|
static int setup_filter_graphs(struct impl *impl, bool force)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
@ -1382,6 +1384,20 @@ static int setup_filter_graphs(struct impl *impl, bool force)
|
||||||
position = in->format.info.raw.position;
|
position = in->format.info.raw.position;
|
||||||
impl->maxports = SPA_MAX(in->format.info.raw.channels, out->format.info.raw.channels);
|
impl->maxports = SPA_MAX(in->format.info.raw.channels, out->format.info.raw.channels);
|
||||||
|
|
||||||
|
if (force) {
|
||||||
|
/* A forced setup deactivates and re-instantiates each graph below,
|
||||||
|
* which frees and recreates the underlying plugin handles. Pull the
|
||||||
|
* graphs out of the data-loop's view first (under the loop lock, via
|
||||||
|
* sync_filter_graph) so the RT thread cannot run a graph while its
|
||||||
|
* handles are NULL during the rebuild. They are republished by the
|
||||||
|
* sync_filter_graph() that follows setup. */
|
||||||
|
spa_list_for_each(g, &impl->active_graphs, link) {
|
||||||
|
if (!g->removing)
|
||||||
|
g->setup = false;
|
||||||
|
}
|
||||||
|
sync_filter_graph(impl);
|
||||||
|
}
|
||||||
|
|
||||||
spa_list_for_each_safe(g, t, &impl->active_graphs, link) {
|
spa_list_for_each_safe(g, t, &impl->active_graphs, link) {
|
||||||
if (g->removing)
|
if (g->removing)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue