webrtc: Fix a race on shutdown.
The main context can disappear in gst_webrtc_bin_enqueue_task() between checking the is_closed flag and enqueueing a source on the main context. Protect the main context with the object lock instead of the PC lock, and hold a ref briefly to make sure it stays alive. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1741>
This commit is contained in:
parent
80a56c25a6
commit
af90778314
@ -713,9 +713,12 @@ _gst_pc_thread (GstWebRTCBin * webrtc)
|
|||||||
* tasks */
|
* tasks */
|
||||||
g_main_loop_run (webrtc->priv->loop);
|
g_main_loop_run (webrtc->priv->loop);
|
||||||
|
|
||||||
PC_LOCK (webrtc);
|
GST_OBJECT_LOCK (webrtc);
|
||||||
g_main_context_unref (webrtc->priv->main_context);
|
g_main_context_unref (webrtc->priv->main_context);
|
||||||
webrtc->priv->main_context = NULL;
|
webrtc->priv->main_context = NULL;
|
||||||
|
GST_OBJECT_UNLOCK (webrtc);
|
||||||
|
|
||||||
|
PC_LOCK (webrtc);
|
||||||
g_main_loop_unref (webrtc->priv->loop);
|
g_main_loop_unref (webrtc->priv->loop);
|
||||||
webrtc->priv->loop = NULL;
|
webrtc->priv->loop = NULL;
|
||||||
PC_COND_BROADCAST (webrtc);
|
PC_COND_BROADCAST (webrtc);
|
||||||
@ -744,8 +747,11 @@ _start_thread (GstWebRTCBin * webrtc)
|
|||||||
static void
|
static void
|
||||||
_stop_thread (GstWebRTCBin * webrtc)
|
_stop_thread (GstWebRTCBin * webrtc)
|
||||||
{
|
{
|
||||||
PC_LOCK (webrtc);
|
GST_OBJECT_LOCK (webrtc);
|
||||||
webrtc->priv->is_closed = TRUE;
|
webrtc->priv->is_closed = TRUE;
|
||||||
|
GST_OBJECT_UNLOCK (webrtc);
|
||||||
|
|
||||||
|
PC_LOCK (webrtc);
|
||||||
g_main_loop_quit (webrtc->priv->loop);
|
g_main_loop_quit (webrtc->priv->loop);
|
||||||
while (webrtc->priv->loop)
|
while (webrtc->priv->loop)
|
||||||
PC_COND_WAIT (webrtc);
|
PC_COND_WAIT (webrtc);
|
||||||
@ -804,16 +810,22 @@ gst_webrtc_bin_enqueue_task (GstWebRTCBin * webrtc, GstWebRTCBinFunc func,
|
|||||||
gpointer data, GDestroyNotify notify, GstPromise * promise)
|
gpointer data, GDestroyNotify notify, GstPromise * promise)
|
||||||
{
|
{
|
||||||
GstWebRTCBinTask *op;
|
GstWebRTCBinTask *op;
|
||||||
|
GMainContext *ctx;
|
||||||
GSource *source;
|
GSource *source;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_WEBRTC_BIN (webrtc), FALSE);
|
g_return_val_if_fail (GST_IS_WEBRTC_BIN (webrtc), FALSE);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (webrtc);
|
||||||
if (webrtc->priv->is_closed) {
|
if (webrtc->priv->is_closed) {
|
||||||
|
GST_OBJECT_UNLOCK (webrtc);
|
||||||
GST_DEBUG_OBJECT (webrtc, "Peerconnection is closed, aborting execution");
|
GST_DEBUG_OBJECT (webrtc, "Peerconnection is closed, aborting execution");
|
||||||
if (notify)
|
if (notify)
|
||||||
notify (data);
|
notify (data);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
ctx = g_main_context_ref (webrtc->priv->main_context);
|
||||||
|
GST_OBJECT_UNLOCK (webrtc);
|
||||||
|
|
||||||
op = g_new0 (GstWebRTCBinTask, 1);
|
op = g_new0 (GstWebRTCBinTask, 1);
|
||||||
op->webrtc = webrtc;
|
op->webrtc = webrtc;
|
||||||
op->op = func;
|
op->op = func;
|
||||||
@ -826,8 +838,9 @@ gst_webrtc_bin_enqueue_task (GstWebRTCBin * webrtc, GstWebRTCBinFunc func,
|
|||||||
g_source_set_priority (source, G_PRIORITY_DEFAULT);
|
g_source_set_priority (source, G_PRIORITY_DEFAULT);
|
||||||
g_source_set_callback (source, (GSourceFunc) _execute_op, op,
|
g_source_set_callback (source, (GSourceFunc) _execute_op, op,
|
||||||
(GDestroyNotify) _free_op);
|
(GDestroyNotify) _free_op);
|
||||||
g_source_attach (source, webrtc->priv->main_context);
|
g_source_attach (source, ctx);
|
||||||
g_source_unref (source);
|
g_source_unref (source);
|
||||||
|
g_main_context_unref (ctx);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user