mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-11-05 10:38:54 +01:00
magic gcan functions
This commit is contained in:
@@ -1123,12 +1123,22 @@ g_cancellable_remove_critical_thread (GCancellable *cancellable,
|
|||||||
* g_thread_enter_critical_section_using_handle() is called and the
|
* g_thread_enter_critical_section_using_handle() is called and the
|
||||||
* result is returned.
|
* result is returned.
|
||||||
*
|
*
|
||||||
* The result is that the returned handle will poll as ready if
|
* You cannot call g_thread_wakeup() on @thread for yourself because you
|
||||||
|
* cannot acquire the lock that this function will use the establish the
|
||||||
|
* critical section.
|
||||||
|
*
|
||||||
|
* The overall result is that the returned handle will poll as ready if
|
||||||
* @cancellable is triggered.
|
* @cancellable is triggered.
|
||||||
*
|
*
|
||||||
* You must call g_cancellable_leave_critical_section() when you are
|
* You must call g_cancellable_leave_critical_section() when you are
|
||||||
* done.
|
* done.
|
||||||
*
|
*
|
||||||
|
* If @cancellable is %NULL then this function will still enter the
|
||||||
|
* critical section and return a valid handle, but that handle will
|
||||||
|
* never become ready. This is relatively low-overhead but you could
|
||||||
|
* save yourself the trouble of polling on an extra object by checking
|
||||||
|
* for @cancellable being %NULL before calling this function.
|
||||||
|
*
|
||||||
* The example in the documentation for
|
* The example in the documentation for
|
||||||
* g_thread_enter_critical_section_using_handle() could be written
|
* g_thread_enter_critical_section_using_handle() could be written
|
||||||
* using GCancellable as follows:
|
* using GCancellable as follows:
|
||||||
@@ -1137,7 +1147,6 @@ g_cancellable_remove_critical_thread (GCancellable *cancellable,
|
|||||||
* static gpointer worker (gpointer user_data) {
|
* static gpointer worker (gpointer user_data) {
|
||||||
* GCancellable *cancellable = user_data;
|
* GCancellable *cancellable = user_data;
|
||||||
* GThread *self = g_thread_self ();
|
* GThread *self = g_thread_self ();
|
||||||
* gboolean should_exit = FALSE;
|
|
||||||
*
|
*
|
||||||
* while (TRUE)
|
* while (TRUE)
|
||||||
* {
|
* {
|
||||||
@@ -1156,7 +1165,6 @@ g_cancellable_remove_critical_thread (GCancellable *cancellable,
|
|||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* void start_cancellable_worker (GCancellable *cancellable) {
|
* void start_cancellable_worker (GCancellable *cancellable) {
|
||||||
* g_atomic_set (&continue_work, 1);
|
|
||||||
* g_thread_unref (g_thread_new ("worker", worker, cancellable));
|
* g_thread_unref (g_thread_new ("worker", worker, cancellable));
|
||||||
* }
|
* }
|
||||||
* ]|
|
* ]|
|
||||||
@@ -1172,30 +1180,35 @@ g_cancellable_enter_critical_section_using_handle (GCancellable *cancellable,
|
|||||||
GThread *thread,
|
GThread *thread,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
if (cancellable)
|
ghandle result = G_HANDLE_NULL;
|
||||||
|
|
||||||
|
/* We're about to call a function that is documented as requiring a
|
||||||
|
* lock to be held... without holding a lock.
|
||||||
|
*
|
||||||
|
* That's actually OK because we're operating on thread-local data and
|
||||||
|
* there is no chance that g_thread_wakeup() can be called if the
|
||||||
|
* cancellable is %NULL.
|
||||||
|
*/
|
||||||
|
if (!cancellable)
|
||||||
|
return g_thread_enter_critical_section_using_handle (thread);
|
||||||
|
|
||||||
|
g_mutex_lock (&cancellable_mutex);
|
||||||
|
|
||||||
|
if (!cancellable->priv->cancelled)
|
||||||
{
|
{
|
||||||
gboolean cancelled = FALSE;
|
result = g_thread_enter_critical_section_using_handle (thread);
|
||||||
|
g_cancellable_add_critical_thread (cancellable, thread);
|
||||||
g_mutex_lock (&cancellable_mutex);
|
|
||||||
|
|
||||||
cancelled = cancellable->priv->cancelled;
|
|
||||||
|
|
||||||
if (!cancelled)
|
|
||||||
g_cancellable_add_critical_thread (cancellable, thread);
|
|
||||||
|
|
||||||
g_mutex_unlock (&cancellable_mutex);
|
|
||||||
|
|
||||||
if (cancelled)
|
|
||||||
{
|
|
||||||
g_set_error_literal (error,
|
|
||||||
G_IO_ERROR,
|
|
||||||
G_IO_ERROR_CANCELLED,
|
|
||||||
_("Operation was cancelled"));
|
|
||||||
return G_HANDLE_NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return g_thread_enter_critical_section_using_handle (thread);
|
g_mutex_unlock (&cancellable_mutex);
|
||||||
|
|
||||||
|
if (!g_handle_is_valid (result))
|
||||||
|
g_set_error_literal (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_CANCELLED,
|
||||||
|
_("Operation was cancelled"));
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1223,28 +1236,28 @@ g_cancellable_leave_critical_section (GCancellable *cancellable,
|
|||||||
GThread *thread,
|
GThread *thread,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
g_thread_leave_critical_section (thread);
|
gboolean success = TRUE;
|
||||||
|
|
||||||
if (cancellable)
|
/* See comment above */
|
||||||
|
if (!cancellable)
|
||||||
{
|
{
|
||||||
gboolean cancelled = FALSE;
|
g_thread_leave_critical_section (thread);
|
||||||
|
return TRUE;
|
||||||
g_mutex_lock (&cancellable_mutex);
|
|
||||||
|
|
||||||
g_cancellable_remove_critical_thread (cancellable, thread);
|
|
||||||
cancelled = cancellable->priv->cancelled;
|
|
||||||
|
|
||||||
g_mutex_unlock (&cancellable_mutex);
|
|
||||||
|
|
||||||
if (cancelled)
|
|
||||||
{
|
|
||||||
g_set_error_literal (error,
|
|
||||||
G_IO_ERROR,
|
|
||||||
G_IO_ERROR_CANCELLED,
|
|
||||||
_("Operation was cancelled"));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_mutex_lock (&cancellable_mutex);
|
||||||
|
|
||||||
|
g_cancellable_remove_critical_thread (cancellable, thread);
|
||||||
|
g_thread_leave_critical_section (thread);
|
||||||
|
success = !cancellable->priv->cancelled;
|
||||||
|
|
||||||
|
g_mutex_unlock (&cancellable_mutex);
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
g_set_error_literal (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_CANCELLED,
|
||||||
|
_("Operation was cancelled"));
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user