mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-03 14:42:10 +01:00
Use the atomic integer operations for GMainContext and GMainLoop reference
2004-03-04 Sebastian Wilhelmi <seppi@seppi.de> * glib/gmain.c: Use the atomic integer operations for GMainContext and GMainLoop reference counting. * glib/gmain.c: Hold the main_context_list lock, when iterating the list. Only call g_main_context_wakeup for positive reference count.
This commit is contained in:
parent
6e521087ad
commit
c40b15fc6b
@ -1,3 +1,12 @@
|
|||||||
|
2004-03-04 Sebastian Wilhelmi <seppi@seppi.de>
|
||||||
|
|
||||||
|
* glib/gmain.c: Use the atomic integer operations for GMainContext
|
||||||
|
and GMainLoop reference counting.
|
||||||
|
|
||||||
|
* glib/gmain.c: Hold the main_context_list lock, when iterating
|
||||||
|
the list. Only call g_main_context_wakeup for positive reference
|
||||||
|
count.
|
||||||
|
|
||||||
2004-03-03 Tor Lillqvist <tml@iki.fi>
|
2004-03-03 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glibconfig.h.win32.in: Update to match a configure-generated
|
* glibconfig.h.win32.in: Update to match a configure-generated
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
2004-03-04 Sebastian Wilhelmi <seppi@seppi.de>
|
||||||
|
|
||||||
|
* glib/gmain.c: Use the atomic integer operations for GMainContext
|
||||||
|
and GMainLoop reference counting.
|
||||||
|
|
||||||
|
* glib/gmain.c: Hold the main_context_list lock, when iterating
|
||||||
|
the list. Only call g_main_context_wakeup for positive reference
|
||||||
|
count.
|
||||||
|
|
||||||
2004-03-03 Tor Lillqvist <tml@iki.fi>
|
2004-03-03 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glibconfig.h.win32.in: Update to match a configure-generated
|
* glibconfig.h.win32.in: Update to match a configure-generated
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
2004-03-04 Sebastian Wilhelmi <seppi@seppi.de>
|
||||||
|
|
||||||
|
* glib/gmain.c: Use the atomic integer operations for GMainContext
|
||||||
|
and GMainLoop reference counting.
|
||||||
|
|
||||||
|
* glib/gmain.c: Hold the main_context_list lock, when iterating
|
||||||
|
the list. Only call g_main_context_wakeup for positive reference
|
||||||
|
count.
|
||||||
|
|
||||||
2004-03-03 Tor Lillqvist <tml@iki.fi>
|
2004-03-03 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glibconfig.h.win32.in: Update to match a configure-generated
|
* glibconfig.h.win32.in: Update to match a configure-generated
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
2004-03-04 Sebastian Wilhelmi <seppi@seppi.de>
|
||||||
|
|
||||||
|
* glib/gmain.c: Use the atomic integer operations for GMainContext
|
||||||
|
and GMainLoop reference counting.
|
||||||
|
|
||||||
|
* glib/gmain.c: Hold the main_context_list lock, when iterating
|
||||||
|
the list. Only call g_main_context_wakeup for positive reference
|
||||||
|
count.
|
||||||
|
|
||||||
2004-03-03 Tor Lillqvist <tml@iki.fi>
|
2004-03-03 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glibconfig.h.win32.in: Update to match a configure-generated
|
* glibconfig.h.win32.in: Update to match a configure-generated
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
2004-03-04 Sebastian Wilhelmi <seppi@seppi.de>
|
||||||
|
|
||||||
|
* glib/gmain.c: Use the atomic integer operations for GMainContext
|
||||||
|
and GMainLoop reference counting.
|
||||||
|
|
||||||
|
* glib/gmain.c: Hold the main_context_list lock, when iterating
|
||||||
|
the list. Only call g_main_context_wakeup for positive reference
|
||||||
|
count.
|
||||||
|
|
||||||
2004-03-03 Tor Lillqvist <tml@iki.fi>
|
2004-03-03 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glibconfig.h.win32.in: Update to match a configure-generated
|
* glibconfig.h.win32.in: Update to match a configure-generated
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
2004-03-04 Sebastian Wilhelmi <seppi@seppi.de>
|
||||||
|
|
||||||
|
* glib/gmain.c: Use the atomic integer operations for GMainContext
|
||||||
|
and GMainLoop reference counting.
|
||||||
|
|
||||||
|
* glib/gmain.c: Hold the main_context_list lock, when iterating
|
||||||
|
the list. Only call g_main_context_wakeup for positive reference
|
||||||
|
count.
|
||||||
|
|
||||||
2004-03-03 Tor Lillqvist <tml@iki.fi>
|
2004-03-03 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glibconfig.h.win32.in: Update to match a configure-generated
|
* glibconfig.h.win32.in: Update to match a configure-generated
|
||||||
|
111
glib/gmain.c
111
glib/gmain.c
@ -103,7 +103,7 @@ struct _GMainContext
|
|||||||
GSList *waiters;
|
GSList *waiters;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
guint ref_count;
|
gint ref_count;
|
||||||
|
|
||||||
GPtrArray *pending_dispatches;
|
GPtrArray *pending_dispatches;
|
||||||
gint timeout; /* Timeout for current iteration */
|
gint timeout; /* Timeout for current iteration */
|
||||||
@ -153,7 +153,7 @@ struct _GMainLoop
|
|||||||
{
|
{
|
||||||
GMainContext *context;
|
GMainContext *context;
|
||||||
gboolean is_running;
|
gboolean is_running;
|
||||||
guint ref_count;
|
gint ref_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GTimeoutSource
|
struct _GTimeoutSource
|
||||||
@ -589,13 +589,9 @@ void
|
|||||||
g_main_context_ref (GMainContext *context)
|
g_main_context_ref (GMainContext *context)
|
||||||
{
|
{
|
||||||
g_return_if_fail (context != NULL);
|
g_return_if_fail (context != NULL);
|
||||||
g_return_if_fail (context->ref_count > 0);
|
g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
|
||||||
|
|
||||||
LOCK_CONTEXT (context);
|
g_atomic_int_inc (&context->ref_count);
|
||||||
|
|
||||||
context->ref_count++;
|
|
||||||
|
|
||||||
UNLOCK_CONTEXT (context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If DISABLE_MEM_POOLS is defined, then freeing the
|
/* If DISABLE_MEM_POOLS is defined, then freeing the
|
||||||
@ -618,18 +614,22 @@ poll_rec_list_free (GMainContext *context,
|
|||||||
}
|
}
|
||||||
#endif /* DISABLE_MEM_POOLS */
|
#endif /* DISABLE_MEM_POOLS */
|
||||||
|
|
||||||
static void
|
/**
|
||||||
g_main_context_unref_and_unlock (GMainContext *context)
|
* g_main_context_unref:
|
||||||
|
* @context: a #GMainContext
|
||||||
|
*
|
||||||
|
* Decreases the reference count on a #GMainContext object by one. If
|
||||||
|
* the result is zero, free the context and free all associated memory.
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
g_main_context_unref (GMainContext *context)
|
||||||
{
|
{
|
||||||
GSource *source;
|
GSource *source;
|
||||||
|
g_return_if_fail (context != NULL);
|
||||||
|
g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
|
||||||
|
|
||||||
context->ref_count--;
|
if (!g_atomic_int_dec_and_test (&context->ref_count))
|
||||||
|
|
||||||
if (context->ref_count != 0)
|
|
||||||
{
|
|
||||||
UNLOCK_CONTEXT (context);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
G_LOCK (main_context_list);
|
G_LOCK (main_context_list);
|
||||||
main_context_list = g_slist_remove (main_context_list, context);
|
main_context_list = g_slist_remove (main_context_list, context);
|
||||||
@ -642,7 +642,6 @@ g_main_context_unref_and_unlock (GMainContext *context)
|
|||||||
g_source_destroy_internal (source, context, TRUE);
|
g_source_destroy_internal (source, context, TRUE);
|
||||||
source = next;
|
source = next;
|
||||||
}
|
}
|
||||||
UNLOCK_CONTEXT (context);
|
|
||||||
|
|
||||||
#ifdef G_THREADS_ENABLED
|
#ifdef G_THREADS_ENABLED
|
||||||
g_static_mutex_free (&context->mutex);
|
g_static_mutex_free (&context->mutex);
|
||||||
@ -677,23 +676,6 @@ g_main_context_unref_and_unlock (GMainContext *context)
|
|||||||
g_free (context);
|
g_free (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* g_main_context_unref:
|
|
||||||
* @context: a #GMainContext
|
|
||||||
*
|
|
||||||
* Decreases the reference count on a #GMainContext object by one. If
|
|
||||||
* the result is zero, free the context and free all associated memory.
|
|
||||||
**/
|
|
||||||
void
|
|
||||||
g_main_context_unref (GMainContext *context)
|
|
||||||
{
|
|
||||||
g_return_if_fail (context != NULL);
|
|
||||||
g_return_if_fail (context->ref_count > 0);
|
|
||||||
|
|
||||||
LOCK_CONTEXT (context);
|
|
||||||
g_main_context_unref_and_unlock (context);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef G_THREADS_ENABLED
|
#ifdef G_THREADS_ENABLED
|
||||||
static void
|
static void
|
||||||
g_main_context_init_pipe (GMainContext *context)
|
g_main_context_init_pipe (GMainContext *context)
|
||||||
@ -2636,31 +2618,13 @@ GMainLoop *
|
|||||||
g_main_loop_ref (GMainLoop *loop)
|
g_main_loop_ref (GMainLoop *loop)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (loop != NULL, NULL);
|
g_return_val_if_fail (loop != NULL, NULL);
|
||||||
g_return_val_if_fail (loop->ref_count > 0, NULL);
|
g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, NULL);
|
||||||
|
|
||||||
LOCK_CONTEXT (loop->context);
|
g_atomic_int_inc (&loop->ref_count);
|
||||||
loop->ref_count++;
|
|
||||||
UNLOCK_CONTEXT (loop->context);
|
|
||||||
|
|
||||||
return loop;
|
return loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
g_main_loop_unref_and_unlock (GMainLoop *loop)
|
|
||||||
{
|
|
||||||
loop->ref_count--;
|
|
||||||
if (loop->ref_count == 0)
|
|
||||||
{
|
|
||||||
/* When the ref_count is 0, there can be nobody else using the
|
|
||||||
* loop, so it is safe to unlock before destroying.
|
|
||||||
*/
|
|
||||||
g_main_context_unref_and_unlock (loop->context);
|
|
||||||
g_free (loop);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
UNLOCK_CONTEXT (loop->context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_main_loop_unref:
|
* g_main_loop_unref:
|
||||||
* @loop: a #GMainLoop
|
* @loop: a #GMainLoop
|
||||||
@ -2672,11 +2636,13 @@ void
|
|||||||
g_main_loop_unref (GMainLoop *loop)
|
g_main_loop_unref (GMainLoop *loop)
|
||||||
{
|
{
|
||||||
g_return_if_fail (loop != NULL);
|
g_return_if_fail (loop != NULL);
|
||||||
g_return_if_fail (loop->ref_count > 0);
|
g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
|
||||||
|
|
||||||
LOCK_CONTEXT (loop->context);
|
if (!g_atomic_int_dec_and_test (&loop->ref_count))
|
||||||
|
return;
|
||||||
|
|
||||||
g_main_loop_unref_and_unlock (loop);
|
g_main_context_unref (loop->context);
|
||||||
|
g_free (loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2694,7 +2660,7 @@ g_main_loop_run (GMainLoop *loop)
|
|||||||
GThread *self = G_THREAD_SELF;
|
GThread *self = G_THREAD_SELF;
|
||||||
|
|
||||||
g_return_if_fail (loop != NULL);
|
g_return_if_fail (loop != NULL);
|
||||||
g_return_if_fail (loop->ref_count > 0);
|
g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
|
||||||
|
|
||||||
#ifdef G_THREADS_ENABLED
|
#ifdef G_THREADS_ENABLED
|
||||||
if (!g_main_context_acquire (loop->context))
|
if (!g_main_context_acquire (loop->context))
|
||||||
@ -2711,7 +2677,7 @@ g_main_loop_run (GMainLoop *loop)
|
|||||||
|
|
||||||
LOCK_CONTEXT (loop->context);
|
LOCK_CONTEXT (loop->context);
|
||||||
|
|
||||||
loop->ref_count++;
|
g_atomic_int_inc (&loop->ref_count);
|
||||||
|
|
||||||
if (!loop->is_running)
|
if (!loop->is_running)
|
||||||
loop->is_running = TRUE;
|
loop->is_running = TRUE;
|
||||||
@ -2746,7 +2712,7 @@ g_main_loop_run (GMainLoop *loop)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
loop->ref_count++;
|
g_atomic_int_inc (&loop->ref_count);
|
||||||
loop->is_running = TRUE;
|
loop->is_running = TRUE;
|
||||||
while (loop->is_running)
|
while (loop->is_running)
|
||||||
g_main_context_iterate (loop->context, TRUE, TRUE, self);
|
g_main_context_iterate (loop->context, TRUE, TRUE, self);
|
||||||
@ -2771,7 +2737,7 @@ void
|
|||||||
g_main_loop_quit (GMainLoop *loop)
|
g_main_loop_quit (GMainLoop *loop)
|
||||||
{
|
{
|
||||||
g_return_if_fail (loop != NULL);
|
g_return_if_fail (loop != NULL);
|
||||||
g_return_if_fail (loop->ref_count > 0);
|
g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
|
||||||
|
|
||||||
LOCK_CONTEXT (loop->context);
|
LOCK_CONTEXT (loop->context);
|
||||||
loop->is_running = FALSE;
|
loop->is_running = FALSE;
|
||||||
@ -2797,7 +2763,7 @@ gboolean
|
|||||||
g_main_loop_is_running (GMainLoop *loop)
|
g_main_loop_is_running (GMainLoop *loop)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (loop != NULL, FALSE);
|
g_return_val_if_fail (loop != NULL, FALSE);
|
||||||
g_return_val_if_fail (loop->ref_count > 0, FALSE);
|
g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, FALSE);
|
||||||
|
|
||||||
return loop->is_running;
|
return loop->is_running;
|
||||||
}
|
}
|
||||||
@ -2814,7 +2780,7 @@ GMainContext *
|
|||||||
g_main_loop_get_context (GMainLoop *loop)
|
g_main_loop_get_context (GMainLoop *loop)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (loop != NULL, NULL);
|
g_return_val_if_fail (loop != NULL, NULL);
|
||||||
g_return_val_if_fail (loop->ref_count > 0, NULL);
|
g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, NULL);
|
||||||
|
|
||||||
return loop->context;
|
return loop->context;
|
||||||
}
|
}
|
||||||
@ -2920,7 +2886,7 @@ g_main_context_add_poll (GMainContext *context,
|
|||||||
if (!context)
|
if (!context)
|
||||||
context = g_main_context_default ();
|
context = g_main_context_default ();
|
||||||
|
|
||||||
g_return_if_fail (context->ref_count > 0);
|
g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
|
||||||
g_return_if_fail (fd);
|
g_return_if_fail (fd);
|
||||||
|
|
||||||
LOCK_CONTEXT (context);
|
LOCK_CONTEXT (context);
|
||||||
@ -2992,7 +2958,7 @@ g_main_context_remove_poll (GMainContext *context,
|
|||||||
if (!context)
|
if (!context)
|
||||||
context = g_main_context_default ();
|
context = g_main_context_default ();
|
||||||
|
|
||||||
g_return_if_fail (context->ref_count > 0);
|
g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
|
||||||
g_return_if_fail (fd);
|
g_return_if_fail (fd);
|
||||||
|
|
||||||
LOCK_CONTEXT (context);
|
LOCK_CONTEXT (context);
|
||||||
@ -3094,7 +3060,7 @@ g_main_context_set_poll_func (GMainContext *context,
|
|||||||
if (!context)
|
if (!context)
|
||||||
context = g_main_context_default ();
|
context = g_main_context_default ();
|
||||||
|
|
||||||
g_return_if_fail (context->ref_count > 0);
|
g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
|
||||||
|
|
||||||
LOCK_CONTEXT (context);
|
LOCK_CONTEXT (context);
|
||||||
|
|
||||||
@ -3128,7 +3094,7 @@ g_main_context_get_poll_func (GMainContext *context)
|
|||||||
if (!context)
|
if (!context)
|
||||||
context = g_main_context_default ();
|
context = g_main_context_default ();
|
||||||
|
|
||||||
g_return_val_if_fail (context->ref_count > 0, NULL);
|
g_return_val_if_fail (g_atomic_int_get (&context->ref_count) > 0, NULL);
|
||||||
|
|
||||||
LOCK_CONTEXT (context);
|
LOCK_CONTEXT (context);
|
||||||
result = context->poll_func;
|
result = context->poll_func;
|
||||||
@ -3168,7 +3134,7 @@ g_main_context_wakeup (GMainContext *context)
|
|||||||
if (!context)
|
if (!context)
|
||||||
context = g_main_context_default ();
|
context = g_main_context_default ();
|
||||||
|
|
||||||
g_return_if_fail (context->ref_count > 0);
|
g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
|
||||||
|
|
||||||
LOCK_CONTEXT (context);
|
LOCK_CONTEXT (context);
|
||||||
g_main_context_wakeup_unlocked (context);
|
g_main_context_wakeup_unlocked (context);
|
||||||
@ -3571,15 +3537,20 @@ child_watch_helper_thread (gpointer data)
|
|||||||
read (child_watch_wake_up_pipe[0], b, 20);
|
read (child_watch_wake_up_pipe[0], b, 20);
|
||||||
|
|
||||||
/* We were woken up. Wake up all other contexts in all other threads */
|
/* We were woken up. Wake up all other contexts in all other threads */
|
||||||
G_UNLOCK (main_context_list);
|
G_LOCK (main_context_list);
|
||||||
for (list = main_context_list; list; list = list->next)
|
for (list = main_context_list; list; list = list->next)
|
||||||
{
|
{
|
||||||
GMainContext *context;
|
GMainContext *context;
|
||||||
|
|
||||||
context = list->data;
|
context = list->data;
|
||||||
|
if (g_atomic_int_get (&context->ref_count) > 0)
|
||||||
|
/* Due to racing conditions we can find ref_count == 0, in
|
||||||
|
* that case, however, the context is still not destroyed
|
||||||
|
* and no poll can be active, otherwise the ref_count
|
||||||
|
* wouldn't be 0 */
|
||||||
g_main_context_wakeup (context);
|
g_main_context_wakeup (context);
|
||||||
}
|
}
|
||||||
G_LOCK (main_context_list);
|
G_UNLOCK (main_context_list);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user