mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-16 20:38:48 +02:00
Revert "gcancellable: allow g_cancellable_disconnect from "cancelled" handler on same thread"
This reverts commits 83605e2d0a7b0d39987715cfd046f7b8ef6de94e and 140fa7ee4669adb3827e3ddea5be57f51ee7af3e.
This commit is contained in:
parent
140fa7ee46
commit
6d08d1191b
@ -46,8 +46,8 @@ enum {
|
|||||||
struct _GCancellablePrivate
|
struct _GCancellablePrivate
|
||||||
{
|
{
|
||||||
guint cancelled : 1;
|
guint cancelled : 1;
|
||||||
|
guint cancelled_running : 1;
|
||||||
guint cancelled_running_waiting : 1;
|
guint cancelled_running_waiting : 1;
|
||||||
GThread *cancelled_running_thread;
|
|
||||||
|
|
||||||
guint fd_refcount;
|
guint fd_refcount;
|
||||||
GWakeup *wakeup;
|
GWakeup *wakeup;
|
||||||
@ -122,7 +122,7 @@ g_cancellable_class_init (GCancellableClass *klass)
|
|||||||
* if (cancellable)
|
* if (cancellable)
|
||||||
* id = g_cancellable_connect (cancellable,
|
* id = g_cancellable_connect (cancellable,
|
||||||
* G_CALLBACK (cancelled_handler)
|
* G_CALLBACK (cancelled_handler)
|
||||||
* my_data, NULL);
|
* data, NULL);
|
||||||
*
|
*
|
||||||
* /<!-- -->* cancellable operation here... *<!-- -->/
|
* /<!-- -->* cancellable operation here... *<!-- -->/
|
||||||
*
|
*
|
||||||
@ -260,8 +260,7 @@ g_cancellable_reset (GCancellable *cancellable)
|
|||||||
|
|
||||||
priv = cancellable->priv;
|
priv = cancellable->priv;
|
||||||
|
|
||||||
while (priv->cancelled_running_thread != NULL &&
|
while (priv->cancelled_running)
|
||||||
priv->cancelled_running_thread != g_thread_self ())
|
|
||||||
{
|
{
|
||||||
priv->cancelled_running_waiting = TRUE;
|
priv->cancelled_running_waiting = TRUE;
|
||||||
g_cond_wait (&cancellable_cond, &cancellable_mutex);
|
g_cond_wait (&cancellable_cond, &cancellable_mutex);
|
||||||
@ -493,7 +492,7 @@ g_cancellable_cancel (GCancellable *cancellable)
|
|||||||
}
|
}
|
||||||
|
|
||||||
priv->cancelled = TRUE;
|
priv->cancelled = TRUE;
|
||||||
priv->cancelled_running_thread = g_thread_self ();
|
priv->cancelled_running = TRUE;
|
||||||
|
|
||||||
if (priv->wakeup)
|
if (priv->wakeup)
|
||||||
GLIB_PRIVATE_CALL (g_wakeup_signal) (priv->wakeup);
|
GLIB_PRIVATE_CALL (g_wakeup_signal) (priv->wakeup);
|
||||||
@ -505,7 +504,7 @@ g_cancellable_cancel (GCancellable *cancellable)
|
|||||||
|
|
||||||
g_mutex_lock (&cancellable_mutex);
|
g_mutex_lock (&cancellable_mutex);
|
||||||
|
|
||||||
priv->cancelled_running_thread = NULL;
|
priv->cancelled_running = FALSE;
|
||||||
if (priv->cancelled_running_waiting)
|
if (priv->cancelled_running_waiting)
|
||||||
g_cond_broadcast (&cancellable_cond);
|
g_cond_broadcast (&cancellable_cond);
|
||||||
priv->cancelled_running_waiting = FALSE;
|
priv->cancelled_running_waiting = FALSE;
|
||||||
@ -558,8 +557,6 @@ g_cancellable_connect (GCancellable *cancellable,
|
|||||||
void (*_callback) (GCancellable *cancellable,
|
void (*_callback) (GCancellable *cancellable,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
g_mutex_unlock (&cancellable_mutex);
|
|
||||||
|
|
||||||
_callback = (void *)callback;
|
_callback = (void *)callback;
|
||||||
id = 0;
|
id = 0;
|
||||||
|
|
||||||
@ -574,10 +571,9 @@ g_cancellable_connect (GCancellable *cancellable,
|
|||||||
callback, data,
|
callback, data,
|
||||||
(GClosureNotify) data_destroy_func,
|
(GClosureNotify) data_destroy_func,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
g_mutex_unlock (&cancellable_mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_mutex_unlock (&cancellable_mutex);
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@ -588,20 +584,17 @@ g_cancellable_connect (GCancellable *cancellable,
|
|||||||
* @handler_id: Handler id of the handler to be disconnected, or %0.
|
* @handler_id: Handler id of the handler to be disconnected, or %0.
|
||||||
*
|
*
|
||||||
* Disconnects a handler from a cancellable instance similar to
|
* Disconnects a handler from a cancellable instance similar to
|
||||||
* g_signal_handler_disconnect(). Additionally, in the event that a
|
* g_signal_handler_disconnect(). Additionally, in the event that a
|
||||||
* signal handler is currently running on a different thread, this
|
* signal handler is currently running, this call will block until the
|
||||||
* call will block until the handler has finished.
|
* 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
|
* This avoids a race condition where a thread cancels at the
|
||||||
* same time as the cancellable operation is finished and the
|
* same time as the cancellable operation is finished and the
|
||||||
* signal handler is removed. See #GCancellable::cancelled for
|
* signal handler is removed. See #GCancellable::cancelled for
|
||||||
* details on how to use this.
|
* 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
|
* If @cancellable is %NULL or @handler_id is %0 this function does
|
||||||
* nothing.
|
* nothing.
|
||||||
*
|
*
|
||||||
@ -620,8 +613,7 @@ g_cancellable_disconnect (GCancellable *cancellable,
|
|||||||
|
|
||||||
priv = cancellable->priv;
|
priv = cancellable->priv;
|
||||||
|
|
||||||
while (priv->cancelled_running_thread != NULL &&
|
while (priv->cancelled_running)
|
||||||
priv->cancelled_running_thread != g_thread_self ())
|
|
||||||
{
|
{
|
||||||
priv->cancelled_running_waiting = TRUE;
|
priv->cancelled_running_waiting = TRUE;
|
||||||
g_cond_wait (&cancellable_cond, &cancellable_mutex);
|
g_cond_wait (&cancellable_cond, &cancellable_mutex);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user