Commit 0cf231da authored by Sebastian Dröge's avatar Sebastian Dröge 🍵

multisocketsink: Protect access to the cancellable with the object lock

It's used from the main loop and the streaming thread (unlock_stop()),
and it can sometimes happen that we access it from the main loop in the
short timeframe between destroying and re-creating the cancellable.

Fixes gstreamer/gst-plugins-base#516
parent f441b521
Pipeline #11889 passed with stages
in 77 minutes and 44 seconds
......@@ -634,12 +634,20 @@ gst_multi_socket_sink_handle_client_read (GstMultiSocketSink * sink,
* to write to us except for closing the socket, I guess it's because we
* like to listen to our customers. */
do {
GCancellable *cancellable;
GST_DEBUG_OBJECT (sink, "%s client wants us to read", mhclient->debug);
GST_OBJECT_LOCK (sink);
cancellable = g_object_ref (sink->cancellable);
GST_OBJECT_UNLOCK (sink);
nread =
g_socket_receive (mhclient->handle.socket, mem, MIN (navail,
maxmem), sink->cancellable, &err);
g_object_unref (cancellable);
if (first && nread == 0) {
/* client sent close, so remove it */
GST_DEBUG_OBJECT (sink, "%s client asked for close, removing",
......@@ -909,13 +917,20 @@ gst_multi_socket_sink_handle_client_write (GstMultiSocketSink * sink,
if (mhclient->sending) {
gssize wrote;
GstBuffer *head;
GCancellable *cancellable;
/* pick first buffer from list */
head = GST_BUFFER (mhclient->sending->data);
GST_OBJECT_LOCK (sink);
cancellable = g_object_ref (sink->cancellable);
GST_OBJECT_UNLOCK (sink);
wrote = gst_multi_socket_sink_write (sink, mhclient->handle.socket, head,
mhclient->bufoffset, sink->cancellable, &err);
g_object_unref (cancellable);
if (wrote < 0) {
/* hmm error.. */
if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CLOSED)) {
......@@ -1000,8 +1015,17 @@ ensure_condition (GstMultiSocketSink * sink, GstSocketClient * client,
g_source_unref (client->source);
}
if (condition && sink->main_context) {
GCancellable *cancellable;
GST_OBJECT_LOCK (sink);
cancellable = g_object_ref (sink->cancellable);
GST_OBJECT_UNLOCK (sink);
client->source = g_socket_create_source (mhclient->handle.socket,
condition, sink->cancellable);
g_object_unref (cancellable);
g_source_set_callback (client->source,
(GSourceFunc) gst_multi_socket_sink_socket_condition,
gst_object_ref (sink), (GDestroyNotify) gst_object_unref);
......@@ -1289,8 +1313,10 @@ gst_multi_socket_sink_unlock_stop (GstBaseSink * bsink)
sink = GST_MULTI_SOCKET_SINK (bsink);
GST_DEBUG_OBJECT (sink, "unset flushing");
GST_OBJECT_LOCK (sink);
g_object_unref (sink->cancellable);
sink->cancellable = g_cancellable_new ();
GST_OBJECT_UNLOCK (sink);
return TRUE;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment