Revert "gcancellable: allow g_cancellable_disconnect from "cancelled" handler on...
authorRyan Lortie <desrt@desrt.ca>
Mon, 23 Sep 2013 20:15:34 +0000 (16:15 -0400)
committerRyan Lortie <desrt@desrt.ca>
Mon, 23 Sep 2013 20:15:52 +0000 (16:15 -0400)
This reverts commits 83605e2d0a7b0d39987715cfd046f7b8ef6de94e and
140fa7ee4669adb3827e3ddea5be57f51ee7af3e.

gio/gcancellable.c

index 4522a41..fc56b87 100644 (file)
@@ -46,8 +46,8 @@ enum {
 struct _GCancellablePrivate
 {
   guint cancelled : 1;
+  guint cancelled_running : 1;
   guint cancelled_running_waiting : 1;
-  GThread *cancelled_running_thread;
 
   guint fd_refcount;
   GWakeup *wakeup;
@@ -122,7 +122,7 @@ g_cancellable_class_init (GCancellableClass *klass)
    *     if (cancellable)
    *       id = g_cancellable_connect (cancellable,
    *                                 G_CALLBACK (cancelled_handler)
-   *                                 my_data, NULL);
+   *                                 data, NULL);
    *
    *     /<!-- -->* cancellable operation here... *<!-- -->/
    *
@@ -260,8 +260,7 @@ g_cancellable_reset (GCancellable *cancellable)
 
   priv = cancellable->priv;
 
-  while (priv->cancelled_running_thread != NULL &&
-         priv->cancelled_running_thread != g_thread_self ())
+  while (priv->cancelled_running)
     {
       priv->cancelled_running_waiting = TRUE;
       g_cond_wait (&cancellable_cond, &cancellable_mutex);
@@ -493,7 +492,7 @@ g_cancellable_cancel (GCancellable *cancellable)
     }
 
   priv->cancelled = TRUE;
-  priv->cancelled_running_thread = g_thread_self ();
+  priv->cancelled_running = TRUE;
 
   if (priv->wakeup)
     GLIB_PRIVATE_CALL (g_wakeup_signal) (priv->wakeup);
@@ -505,7 +504,7 @@ g_cancellable_cancel (GCancellable *cancellable)
 
   g_mutex_lock (&cancellable_mutex);
 
-  priv->cancelled_running_thread = NULL;
+  priv->cancelled_running = FALSE;
   if (priv->cancelled_running_waiting)
     g_cond_broadcast (&cancellable_cond);
   priv->cancelled_running_waiting = FALSE;
@@ -558,8 +557,6 @@ g_cancellable_connect (GCancellable   *cancellable,
       void (*_callback) (GCancellable *cancellable,
                          gpointer      user_data);
 
-      g_mutex_unlock (&cancellable_mutex);
-
       _callback = (void *)callback;
       id = 0;
 
@@ -574,10 +571,9 @@ g_cancellable_connect (GCancellable   *cancellable,
                                   callback, data,
                                   (GClosureNotify) data_destroy_func,
                                   0);
-
-      g_mutex_unlock (&cancellable_mutex);
     }
 
+  g_mutex_unlock (&cancellable_mutex);
 
   return id;
 }
@@ -588,20 +584,17 @@ g_cancellable_connect (GCancellable   *cancellable,
  * @handler_id: Handler id of the handler to be disconnected, or %0.
  *
  * Disconnects a handler from a cancellable instance similar to
- * g_signal_handler_disconnect(). Additionally, in the event that a
- * signal handler is currently running on a different thread, this
- * call will block until the handler has finished.
+ * g_signal_handler_disconnect().  Additionally, in the event that a
+ * signal handler is currently running, this call will block until the
+ * handler has finished.  Calling this function from a
+ * #GCancellable::cancelled signal handler will therefore result in a
+ * deadlock.
  *
  * This avoids a race condition where a thread cancels at the
  * same time as the cancellable operation is finished and the
  * signal handler is removed. See #GCancellable::cancelled for
  * details on how to use this.
  *
- * Note, since 2.38 it is safe to call this function from a
- * #GCancellable::cancelled signal handler, something which would
- * previously have caused a deadlock. However, it is not a good idea
- * to disconnect a signal handler from inside its *own* signal handler.
- *
  * If @cancellable is %NULL or @handler_id is %0 this function does
  * nothing.
  *
@@ -620,8 +613,7 @@ g_cancellable_disconnect (GCancellable  *cancellable,
 
   priv = cancellable->priv;
 
-  while (priv->cancelled_running_thread != NULL &&
-         priv->cancelled_running_thread != g_thread_self ())
+  while (priv->cancelled_running)
     {
       priv->cancelled_running_waiting = TRUE;
       g_cond_wait (&cancellable_cond, &cancellable_mutex);