summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Santos <ts.santos@sisa.samsung.com>2013-12-20 19:42:52 -0300
committerSebastian Dröge <sebastian@centricular.com>2014-02-04 17:25:49 +0100
commit98863e5fc681e0c43f06e7fc9d41da941845d23b (patch)
treeafa7ad9f8b36ed17942cc12cc2076746b42732e1
parentafab2cfa7bec94c865c1f98a89be6384b8dfc0ce (diff)
downloadgstreamer-plugins-bad-98863e5fc681e0c43f06e7fc9d41da941845d23b.tar.gz
uridownloader: fix deadlock near EOS
A deadlock can happen when the source sends EOS when being put to NULL as the object lock is being held by the thread that sets the element to NULL and is needed by the event handler.
-rw-r--r--gst-libs/gst/uridownloader/gsturidownloader.c66
1 files changed, 29 insertions, 37 deletions
diff --git a/gst-libs/gst/uridownloader/gsturidownloader.c b/gst-libs/gst/uridownloader/gsturidownloader.c
index 28e0aff79..d4c9fa775 100644
--- a/gst-libs/gst/uridownloader/gsturidownloader.c
+++ b/gst-libs/gst/uridownloader/gsturidownloader.c
@@ -249,41 +249,6 @@ done:
}
}
-/* Must be called with mutex locked. */
-static void
-gst_uri_downloader_stop (GstUriDownloader * downloader)
-{
- GstPad *pad;
- GstElement *urisrc;
-
- if (!downloader->priv->urisrc)
- return;
-
- GST_DEBUG_OBJECT (downloader, "Stopping source element %s",
- GST_ELEMENT_NAME (downloader->priv->urisrc));
-
- /* remove the bus' sync handler */
- gst_bus_set_sync_handler (downloader->priv->bus, NULL, NULL, NULL);
- /* unlink the source element from the internal pad */
- pad = gst_pad_get_peer (downloader->priv->pad);
- if (pad) {
- gst_pad_unlink (pad, downloader->priv->pad);
- gst_object_unref (pad);
- }
- urisrc = downloader->priv->urisrc;
- downloader->priv->urisrc = NULL;
-
- GST_DEBUG_OBJECT (downloader, "Stopping source element %s",
- GST_ELEMENT_NAME (urisrc));
-
- /* set the element state to NULL */
- gst_bus_set_flushing (downloader->priv->bus, TRUE);
- gst_element_set_state (urisrc, GST_STATE_NULL);
- gst_element_get_state (urisrc, NULL, NULL, GST_CLOCK_TIME_NONE);
- gst_element_set_bus (urisrc, NULL);
- gst_object_unref (urisrc);
-}
-
void
gst_uri_downloader_reset (GstUriDownloader * downloader)
{
@@ -464,8 +429,35 @@ gst_uri_downloader_fetch_uri_with_range (GstUriDownloader * downloader,
quit:
{
- gst_uri_downloader_stop (downloader);
- GST_OBJECT_UNLOCK (downloader);
+ if (downloader->priv->urisrc) {
+ GstPad *pad;
+ GstElement *urisrc;
+
+ GST_DEBUG_OBJECT (downloader, "Stopping source element %s",
+ GST_ELEMENT_NAME (downloader->priv->urisrc));
+
+ /* remove the bus' sync handler */
+ gst_bus_set_sync_handler (downloader->priv->bus, NULL, NULL, NULL);
+ /* unlink the source element from the internal pad */
+ pad = gst_pad_get_peer (downloader->priv->pad);
+ if (pad) {
+ gst_pad_unlink (pad, downloader->priv->pad);
+ gst_object_unref (pad);
+ }
+ urisrc = downloader->priv->urisrc;
+ downloader->priv->urisrc = NULL;
+ GST_OBJECT_UNLOCK (downloader);
+
+ GST_DEBUG_OBJECT (downloader, "Stopping source element %s",
+ GST_ELEMENT_NAME (urisrc));
+
+ /* set the element state to NULL */
+ gst_bus_set_flushing (downloader->priv->bus, TRUE);
+ gst_element_set_state (urisrc, GST_STATE_NULL);
+ gst_element_get_state (urisrc, NULL, NULL, GST_CLOCK_TIME_NONE);
+ gst_element_set_bus (urisrc, NULL);
+ gst_object_unref (urisrc);
+ }
g_mutex_unlock (&downloader->priv->download_lock);
return download;
}