[tracker] libtracker-extract: Fix GCancellable deadlock



commit 95f6d0574b1f4746ff91007e2cf8bcff9afd53ae
Author: Sam Thursfield <sam thursfield codethink co uk>
Date:   Mon May 21 01:33:20 2012 +0900

    libtracker-extract: Fix GCancellable deadlock
    
    Triggering one cancellable in another's callback is a bad idea, because
    these objects share a single global mutex. This can be triggered by
    removing a USB stick during the extraction process.
    
    There's no real need to use two separate cancellables for the same
    file here.
    
    Fixes GB#676433.

 src/libtracker-extract/tracker-extract-client.c |   27 +++++-----------------
 1 files changed, 6 insertions(+), 21 deletions(-)
---
diff --git a/src/libtracker-extract/tracker-extract-client.c b/src/libtracker-extract/tracker-extract-client.c
index 4e2746b..21b614a 100644
--- a/src/libtracker-extract/tracker-extract-client.c
+++ b/src/libtracker-extract/tracker-extract-client.c
@@ -48,12 +48,10 @@ typedef struct {
 	GOutputStream *output_stream;
 	SendAndSpliceCallback callback;
 	GCancellable *cancellable;
-	GCancellable *inner_cancellable;
 	gpointer data;
 	gboolean splice_finished;
 	gboolean dbus_finished;
 	GError *error;
-	guint cancel_handler_id;
 } SendAndSpliceData;
 
 typedef struct {
@@ -61,13 +59,6 @@ typedef struct {
 	GSimpleAsyncResult *res;
 } MetadataCallData;
 
-static void
-propagate_cancellation (GCancellable *cancellable,
-                        GCancellable *inner_cancellable)
-{
-	g_cancellable_cancel (inner_cancellable);
-}
-
 static SendAndSpliceData *
 send_and_splice_data_new (GInputStream          *unix_input_stream,
                           GInputStream          *buffered_input_stream,
@@ -82,15 +73,11 @@ send_and_splice_data_new (GInputStream          *unix_input_stream,
 	data->unix_input_stream = unix_input_stream;
 	data->buffered_input_stream = buffered_input_stream;
 	data->output_stream = output_stream;
-	data->inner_cancellable = g_cancellable_new ();
 
 	if (cancellable) {
 		data->cancellable = g_object_ref (cancellable);
-
-		data->cancel_handler_id =
-			g_cancellable_connect (data->cancellable,
-			                       G_CALLBACK (propagate_cancellation),
-			                       data->inner_cancellable, NULL);
+	} else {
+		data->cancellable = g_cancellable_new ();
 	}
 
 	data->callback = callback;
@@ -103,7 +90,6 @@ static void
 send_and_splice_data_free (SendAndSpliceData *data)
 {
 	if (data->cancellable) {
-		g_cancellable_disconnect (data->cancellable, data->cancel_handler_id);
 		g_object_unref (data->cancellable);
 	}
 
@@ -113,7 +99,6 @@ send_and_splice_data_free (SendAndSpliceData *data)
 	g_object_unref (data->unix_input_stream);
 	g_object_unref (data->buffered_input_stream);
 	g_object_unref (data->output_stream);
-	g_object_unref (data->inner_cancellable);
 
 	if (data->error) {
 		g_error_free (data->error);
@@ -177,7 +162,7 @@ send_and_splice_splice_callback (GObject      *source,
 
 		/* Ensure the other operation is cancelled */
 		if (!data->dbus_finished) {
-			g_cancellable_cancel (data->inner_cancellable);
+			g_cancellable_cancel (data->cancellable);
 		}
 	}
 
@@ -217,7 +202,7 @@ send_and_splice_dbus_callback (GObject      *source,
 
 		/* Ensure the other operation is cancelled */
 		if (!data->splice_finished) {
-			g_cancellable_cancel (data->inner_cancellable);
+			g_cancellable_cancel (data->cancellable);
 		}
 	}
 
@@ -258,7 +243,7 @@ dbus_send_and_splice_async (GDBusConnection       *connection,
 	                                           G_DBUS_SEND_MESSAGE_FLAGS_NONE,
 	                                           -1,
 	                                           NULL,
-	                                           data->inner_cancellable,
+	                                           cancellable,
 	                                           send_and_splice_dbus_callback,
 	                                           data);
 
@@ -267,7 +252,7 @@ dbus_send_and_splice_async (GDBusConnection       *connection,
 	                              G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
 	                              G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
 	                              0,
-	                              data->inner_cancellable,
+	                              cancellable,
 	                              send_and_splice_splice_callback,
 	                              data);
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]