From de2e08a07a4324af53e7edcf29b39a93ec15d230 Mon Sep 17 00:00:00 2001 From: Bartosz Kokoszko Date: Fri, 19 Jul 2019 10:23:04 +0200 Subject: [PATCH] pipeline: refine pipeline_free() function This change allows us to free components and pipelines in any order. Added setting component pointer to NULL after comp_free() invocation. In pipeline_free() there is a incovation of pipeline_comp_free() only if component pointer is not NULL. Signed-off-by: Bartosz Kokoszko --- src/audio/pipeline.c | 24 +++++++++++++----------- src/ipc/ipc.c | 15 ++++++++++++++- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/audio/pipeline.c b/src/audio/pipeline.c index b161d70d1..632e00ff3 100644 --- a/src/audio/pipeline.c +++ b/src/audio/pipeline.c @@ -216,22 +216,24 @@ int pipeline_free(struct pipeline *p) trace_pipe_with_ids(p, "pipeline_free()"); /* make sure we are not in use */ - if (p->source_comp->state > COMP_STATE_READY) { - trace_pipe_error_with_ids(p, "pipeline_free() error: Pipeline" - " in use, %u, %u", - p->source_comp->comp.id, - p->source_comp->state); - return -EBUSY; + if (p->source_comp) { + if (p->source_comp->state > COMP_STATE_READY) { + trace_pipe_error_with_ids(p, "pipeline_free() error: " + "Pipeline in use, %u, %u", + p->source_comp->comp.id, + p->source_comp->state); + return -EBUSY; + } + + data.start = p->source_comp; + + /* disconnect components */ + pipeline_comp_free(p->source_comp, &data, PPL_DIR_DOWNSTREAM); } /* remove from any scheduling */ schedule_task_free(&p->pipe_task); - data.start = p->source_comp; - - /* disconnect components */ - pipeline_comp_free(p->source_comp, &data, PPL_DIR_DOWNSTREAM); - /* now free the pipeline */ rfree(p); diff --git a/src/ipc/ipc.c b/src/ipc/ipc.c index 9ed2e5deb..2eed30dd9 100644 --- a/src/ipc/ipc.c +++ b/src/ipc/ipc.c @@ -170,6 +170,19 @@ int ipc_comp_free(struct ipc *ipc, uint32_t comp_id) /* free component and remove from list */ comp_free(icd->cd); + + /* set pipeline sink/source/sched pointers to NULL if needed */ + if (icd->cd->pipeline) { + if (icd->cd == icd->cd->pipeline->source_comp) + icd->cd->pipeline->source_comp = NULL; + if (icd->cd == icd->cd->pipeline->sink_comp) + icd->cd->pipeline->sink_comp = NULL; + if (icd->cd == icd->cd->pipeline->sched_comp) + icd->cd->pipeline->sched_comp = NULL; + } + + icd->cd = NULL; + list_item_del(&icd->list); rfree(icd); @@ -343,7 +356,7 @@ int ipc_pipeline_free(struct ipc *ipc, uint32_t comp_id) "pipeline_free() failed"); return ret; } - + ipc_pipe->pipeline = NULL; list_item_del(&ipc_pipe->list); rfree(ipc_pipe);