Modified: trunk/Source/WebCore/ChangeLog (177340 => 177341)
--- trunk/Source/WebCore/ChangeLog 2014-12-16 08:16:46 UTC (rev 177340)
+++ trunk/Source/WebCore/ChangeLog 2014-12-16 08:17:58 UTC (rev 177341)
@@ -1,3 +1,17 @@
+2014-12-16 Sebastian Dröge <sebast...@centricular.com>
+
+ [GStreamer] Fix deadlock when shutting down AudioDestination
+ https://bugs.webkit.org/show_bug.cgi?id=139496
+
+ Reviewed by Philippe Normand.
+
+ * platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp:
+ (webKitWebAudioSrcLoop):
+ (webKitWebAudioSrcChangeState):
+ Sometimes we would wait forever for the task to shut down. This
+ was happening because of a bug in GStreamer that caused joining
+ a paused task to deadlock.
+
2014-12-15 Dhi Aurrahman <diorah...@rockybars.com>
Extend :lang()'s selector checker to handle ranges with '*' properly and perform matching within the ASCII range
Modified: trunk/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp (177340 => 177341)
--- trunk/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp 2014-12-16 08:16:46 UTC (rev 177340)
+++ trunk/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp 2014-12-16 08:17:58 UTC (rev 177341)
@@ -314,7 +314,7 @@
ASSERT(priv->provider);
if (!priv->provider || !priv->bus) {
GST_ELEMENT_ERROR(src, CORE, FAILED, ("Internal WebAudioSrc error"), ("Can't start without provider or bus"));
- gst_task_pause(src->priv->task.get());
+ gst_task_stop(src->priv->task.get());
return;
}
@@ -339,8 +339,11 @@
g_free(buffer);
channelBufferList = g_slist_delete_link(channelBufferList, channelBufferList);
}
- GST_ELEMENT_ERROR(src, CORE, PAD, ("Internal WebAudioSrc error"), ("Failed to allocate buffer for flow: %s", gst_flow_get_name(ret)));
- gst_task_pause(src->priv->task.get());
+
+ // FLUSHING and EOS are not errors.
+ if (ret < GST_FLOW_EOS || ret == GST_FLOW_NOT_LINKED)
+ GST_ELEMENT_ERROR(src, CORE, PAD, ("Internal WebAudioSrc error"), ("Failed to allocate buffer for flow: %s", gst_flow_get_name(ret)));
+ gst_task_stop(src->priv->task.get());
return;
}
@@ -359,6 +362,7 @@
GSList* sourcesIt = priv->sources;
GSList* buffersIt = channelBufferList;
+ GstFlowReturn ret = GST_FLOW_OK;
for (i = 0; sourcesIt && buffersIt; sourcesIt = g_slist_next(sourcesIt), buffersIt = g_slist_next(buffersIt), ++i) {
GstElement* appsrc = static_cast<GstElement*>(sourcesIt->data);
AudioSrcBuffer* buffer = static_cast<AudioSrcBuffer*>(buffersIt->data);
@@ -368,11 +372,16 @@
gst_buffer_unmap(channelBuffer, &buffer->info);
g_free(buffer);
- GstFlowReturn ret = gst_app_src_push_buffer(GST_APP_SRC(appsrc), channelBuffer);
- if (ret != GST_FLOW_OK) {
- GST_ELEMENT_ERROR(src, CORE, PAD, ("Internal WebAudioSrc error"), ("Failed to push buffer on %s flow: %s", GST_OBJECT_NAME(appsrc), gst_flow_get_name(ret)));
- gst_task_pause(src->priv->task.get());
- }
+ if (ret == GST_FLOW_OK) {
+ ret = gst_app_src_push_buffer(GST_APP_SRC(appsrc), channelBuffer);
+ if (ret != GST_FLOW_OK) {
+ // FLUSHING and EOS are not errors.
+ if (ret < GST_FLOW_EOS || ret == GST_FLOW_NOT_LINKED)
+ GST_ELEMENT_ERROR(src, CORE, PAD, ("Internal WebAudioSrc error"), ("Failed to push buffer on %s flow: %s", GST_OBJECT_NAME(appsrc), gst_flow_get_name(ret)));
+ gst_task_stop(src->priv->task.get());
+ }
+ } else
+ gst_buffer_unref(channelBuffer);
}
g_slist_free(channelBufferList);
@@ -417,6 +426,9 @@
}
case GST_STATE_CHANGE_PAUSED_TO_READY:
GST_DEBUG_OBJECT(src, "PAUSED->READY");
+#if GST_CHECK_VERSION(1, 4, 0)
+ gst_buffer_pool_set_flushing(src->priv->pool, TRUE);
+#endif
if (!gst_task_join(src->priv->task.get()))
returnValue = GST_STATE_CHANGE_FAILURE;
gst_buffer_pool_set_active(src->priv->pool, FALSE);