mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-18 12:15:19 +00:00
splitmuxsrc: Stop pad task before cleanup
When stopping the element, make sure the pad task is stopped before destroying the part readers. Closes a race where the pad task might access a freed pointer. Also add a guard against this sort of thing by holding a ref to the reader in the pad loop. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2901>
This commit is contained in:
parent
c2fa0b50ce
commit
4a6c2e6720
1 changed files with 20 additions and 5 deletions
|
@ -748,7 +748,7 @@ gst_splitmux_pad_loop (GstPad * pad)
|
||||||
SplitMuxSrcPad *splitpad = (SplitMuxSrcPad *) (pad);
|
SplitMuxSrcPad *splitpad = (SplitMuxSrcPad *) (pad);
|
||||||
GstSplitMuxSrc *splitmux = (GstSplitMuxSrc *) gst_pad_get_parent (pad);
|
GstSplitMuxSrc *splitmux = (GstSplitMuxSrc *) gst_pad_get_parent (pad);
|
||||||
GstDataQueueItem *item = NULL;
|
GstDataQueueItem *item = NULL;
|
||||||
GstSplitMuxPartReader *reader;
|
GstSplitMuxPartReader *reader = NULL;
|
||||||
GstPad *part_pad;
|
GstPad *part_pad;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
|
@ -762,9 +762,15 @@ gst_splitmux_pad_loop (GstPad * pad)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
part_pad = gst_object_ref (splitpad->part_pad);
|
part_pad = gst_object_ref (splitpad->part_pad);
|
||||||
reader = splitpad->reader;
|
|
||||||
GST_OBJECT_UNLOCK (splitpad);
|
GST_OBJECT_UNLOCK (splitpad);
|
||||||
|
|
||||||
|
SPLITMUX_SRC_LOCK (splitmux);
|
||||||
|
reader = splitpad->reader ? gst_object_ref (splitpad->reader) : NULL;
|
||||||
|
SPLITMUX_SRC_UNLOCK (splitmux);
|
||||||
|
|
||||||
|
if (reader == NULL)
|
||||||
|
goto flushing;
|
||||||
|
|
||||||
GST_LOG_OBJECT (splitpad, "Popping data queue item from %" GST_PTR_FORMAT
|
GST_LOG_OBJECT (splitpad, "Popping data queue item from %" GST_PTR_FORMAT
|
||||||
" pad %" GST_PTR_FORMAT, reader, part_pad);
|
" pad %" GST_PTR_FORMAT, reader, part_pad);
|
||||||
ret = gst_splitmux_part_reader_pop (reader, part_pad, &item);
|
ret = gst_splitmux_part_reader_pop (reader, part_pad, &item);
|
||||||
|
@ -806,6 +812,7 @@ gst_splitmux_pad_loop (GstPad * pad)
|
||||||
}
|
}
|
||||||
g_slice_free (GstDataQueueItem, item);
|
g_slice_free (GstDataQueueItem, item);
|
||||||
|
|
||||||
|
gst_object_unref (reader);
|
||||||
gst_object_unref (part_pad);
|
gst_object_unref (part_pad);
|
||||||
gst_object_unref (splitmux);
|
gst_object_unref (splitmux);
|
||||||
return;
|
return;
|
||||||
|
@ -816,6 +823,8 @@ error:
|
||||||
("Error reading part file %s", GST_STR_NULL (reader->path)));
|
("Error reading part file %s", GST_STR_NULL (reader->path)));
|
||||||
flushing:
|
flushing:
|
||||||
gst_pad_pause_task (pad);
|
gst_pad_pause_task (pad);
|
||||||
|
if (reader != NULL)
|
||||||
|
gst_object_unref (reader);
|
||||||
gst_object_unref (part_pad);
|
gst_object_unref (part_pad);
|
||||||
gst_object_unref (splitmux);
|
gst_object_unref (splitmux);
|
||||||
return;
|
return;
|
||||||
|
@ -1001,14 +1010,12 @@ gst_splitmux_src_stop (GstSplitMuxSrc * splitmux)
|
||||||
|
|
||||||
SPLITMUX_SRC_UNLOCK (splitmux);
|
SPLITMUX_SRC_UNLOCK (splitmux);
|
||||||
|
|
||||||
/* Stop and destroy all parts. We don't need the lock here,
|
/* Stop all part readers. We don't need the lock here,
|
||||||
* because all parts were created in _start() */
|
* because all parts were created in _start() */
|
||||||
for (i = 0; i < splitmux->num_created_parts; i++) {
|
for (i = 0; i < splitmux->num_created_parts; i++) {
|
||||||
if (splitmux->parts[i] == NULL)
|
if (splitmux->parts[i] == NULL)
|
||||||
continue;
|
continue;
|
||||||
gst_splitmux_part_reader_unprepare (splitmux->parts[i]);
|
gst_splitmux_part_reader_unprepare (splitmux->parts[i]);
|
||||||
g_object_unref (splitmux->parts[i]);
|
|
||||||
splitmux->parts[i] = NULL;
|
|
||||||
}
|
}
|
||||||
SPLITMUX_SRC_LOCK (splitmux);
|
SPLITMUX_SRC_LOCK (splitmux);
|
||||||
|
|
||||||
|
@ -1026,6 +1033,14 @@ gst_splitmux_src_stop (GstSplitMuxSrc * splitmux)
|
||||||
g_list_free (pads_list);
|
g_list_free (pads_list);
|
||||||
SPLITMUX_SRC_LOCK (splitmux);
|
SPLITMUX_SRC_LOCK (splitmux);
|
||||||
|
|
||||||
|
/* Now the pad task is stopped we can destroy the readers */
|
||||||
|
for (i = 0; i < splitmux->num_created_parts; i++) {
|
||||||
|
if (splitmux->parts[i] == NULL)
|
||||||
|
continue;
|
||||||
|
g_object_unref (splitmux->parts[i]);
|
||||||
|
splitmux->parts[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
g_free (splitmux->parts);
|
g_free (splitmux->parts);
|
||||||
splitmux->parts = NULL;
|
splitmux->parts = NULL;
|
||||||
splitmux->num_parts = 0;
|
splitmux->num_parts = 0;
|
||||||
|
|
Loading…
Reference in a new issue