diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | ChangeLog.pre-2-0 | 7 | ||||
-rw-r--r-- | ChangeLog.pre-2-10 | 7 | ||||
-rw-r--r-- | ChangeLog.pre-2-12 | 7 | ||||
-rw-r--r-- | ChangeLog.pre-2-2 | 7 | ||||
-rw-r--r-- | ChangeLog.pre-2-4 | 7 | ||||
-rw-r--r-- | ChangeLog.pre-2-6 | 7 | ||||
-rw-r--r-- | ChangeLog.pre-2-8 | 7 | ||||
-rw-r--r-- | glib/gmain.c | 105 | ||||
-rw-r--r-- | glib/gmain.h | 5 | ||||
-rw-r--r-- | gmain.c | 105 | ||||
-rw-r--r-- | gmain.h | 5 |
12 files changed, 214 insertions, 62 deletions
@@ -1,10 +1,15 @@ +Wed Jan 3 14:10:49 2001 Owen Taylor <otaylor@redhat.com> + + * gmain.[ch]: Switch GMainLoop to be ref/unref, use to + make dropping reference to running loop safe. + Wed Dec 13 20:41:49 2000 Owen Taylor <otaylor@redhat.com> * gmain.c (g_source_unref_internal): Unref callback->cb_data if it was still set when the source is freed. (Usually, this will be done by g_source_destroy.) -2001-01-02 Dan Winship <danw@helixcode.com> + 2001-01-02 Dan Winship <danw@helixcode.com> * garray.h (g_array_append_val, g_array_prepend_val, g_array_insert_val): Use parentheses around an argument to make diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 32fd7d2be..a8fbd0000 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,10 +1,15 @@ +Wed Jan 3 14:10:49 2001 Owen Taylor <otaylor@redhat.com> + + * gmain.[ch]: Switch GMainLoop to be ref/unref, use to + make dropping reference to running loop safe. + Wed Dec 13 20:41:49 2000 Owen Taylor <otaylor@redhat.com> * gmain.c (g_source_unref_internal): Unref callback->cb_data if it was still set when the source is freed. (Usually, this will be done by g_source_destroy.) -2001-01-02 Dan Winship <danw@helixcode.com> + 2001-01-02 Dan Winship <danw@helixcode.com> * garray.h (g_array_append_val, g_array_prepend_val, g_array_insert_val): Use parentheses around an argument to make diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 32fd7d2be..a8fbd0000 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,10 +1,15 @@ +Wed Jan 3 14:10:49 2001 Owen Taylor <otaylor@redhat.com> + + * gmain.[ch]: Switch GMainLoop to be ref/unref, use to + make dropping reference to running loop safe. + Wed Dec 13 20:41:49 2000 Owen Taylor <otaylor@redhat.com> * gmain.c (g_source_unref_internal): Unref callback->cb_data if it was still set when the source is freed. (Usually, this will be done by g_source_destroy.) -2001-01-02 Dan Winship <danw@helixcode.com> + 2001-01-02 Dan Winship <danw@helixcode.com> * garray.h (g_array_append_val, g_array_prepend_val, g_array_insert_val): Use parentheses around an argument to make diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 32fd7d2be..a8fbd0000 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,10 +1,15 @@ +Wed Jan 3 14:10:49 2001 Owen Taylor <otaylor@redhat.com> + + * gmain.[ch]: Switch GMainLoop to be ref/unref, use to + make dropping reference to running loop safe. + Wed Dec 13 20:41:49 2000 Owen Taylor <otaylor@redhat.com> * gmain.c (g_source_unref_internal): Unref callback->cb_data if it was still set when the source is freed. (Usually, this will be done by g_source_destroy.) -2001-01-02 Dan Winship <danw@helixcode.com> + 2001-01-02 Dan Winship <danw@helixcode.com> * garray.h (g_array_append_val, g_array_prepend_val, g_array_insert_val): Use parentheses around an argument to make diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 32fd7d2be..a8fbd0000 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,10 +1,15 @@ +Wed Jan 3 14:10:49 2001 Owen Taylor <otaylor@redhat.com> + + * gmain.[ch]: Switch GMainLoop to be ref/unref, use to + make dropping reference to running loop safe. + Wed Dec 13 20:41:49 2000 Owen Taylor <otaylor@redhat.com> * gmain.c (g_source_unref_internal): Unref callback->cb_data if it was still set when the source is freed. (Usually, this will be done by g_source_destroy.) -2001-01-02 Dan Winship <danw@helixcode.com> + 2001-01-02 Dan Winship <danw@helixcode.com> * garray.h (g_array_append_val, g_array_prepend_val, g_array_insert_val): Use parentheses around an argument to make diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 32fd7d2be..a8fbd0000 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,10 +1,15 @@ +Wed Jan 3 14:10:49 2001 Owen Taylor <otaylor@redhat.com> + + * gmain.[ch]: Switch GMainLoop to be ref/unref, use to + make dropping reference to running loop safe. + Wed Dec 13 20:41:49 2000 Owen Taylor <otaylor@redhat.com> * gmain.c (g_source_unref_internal): Unref callback->cb_data if it was still set when the source is freed. (Usually, this will be done by g_source_destroy.) -2001-01-02 Dan Winship <danw@helixcode.com> + 2001-01-02 Dan Winship <danw@helixcode.com> * garray.h (g_array_append_val, g_array_prepend_val, g_array_insert_val): Use parentheses around an argument to make diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 32fd7d2be..a8fbd0000 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,10 +1,15 @@ +Wed Jan 3 14:10:49 2001 Owen Taylor <otaylor@redhat.com> + + * gmain.[ch]: Switch GMainLoop to be ref/unref, use to + make dropping reference to running loop safe. + Wed Dec 13 20:41:49 2000 Owen Taylor <otaylor@redhat.com> * gmain.c (g_source_unref_internal): Unref callback->cb_data if it was still set when the source is freed. (Usually, this will be done by g_source_destroy.) -2001-01-02 Dan Winship <danw@helixcode.com> + 2001-01-02 Dan Winship <danw@helixcode.com> * garray.h (g_array_append_val, g_array_prepend_val, g_array_insert_val): Use parentheses around an argument to make diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 32fd7d2be..a8fbd0000 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,10 +1,15 @@ +Wed Jan 3 14:10:49 2001 Owen Taylor <otaylor@redhat.com> + + * gmain.[ch]: Switch GMainLoop to be ref/unref, use to + make dropping reference to running loop safe. + Wed Dec 13 20:41:49 2000 Owen Taylor <otaylor@redhat.com> * gmain.c (g_source_unref_internal): Unref callback->cb_data if it was still set when the source is freed. (Usually, this will be done by g_source_destroy.) -2001-01-02 Dan Winship <danw@helixcode.com> + 2001-01-02 Dan Winship <danw@helixcode.com> * garray.h (g_array_append_val, g_array_prepend_val, g_array_insert_val): Use parentheses around an argument to make diff --git a/glib/gmain.c b/glib/gmain.c index 61957e213..29af3b0e7 100644 --- a/glib/gmain.c +++ b/glib/gmain.c @@ -131,6 +131,7 @@ struct _GMainLoop { GMainContext *context; gboolean is_running; + guint ref_count; #ifdef G_THREADS_ENABLED GMutex *mutex; @@ -2012,7 +2013,8 @@ g_main_loop_new (GMainContext *context, loop = g_new0 (GMainLoop, 1); loop->context = context; loop->is_running = is_running != FALSE; - + loop->ref_count = 1; + #ifdef G_THREADS_ENABLED if (g_thread_supported ()) loop->mutex = g_mutex_new (); @@ -2025,6 +2027,66 @@ g_main_loop_new (GMainContext *context, } /** + * g_main_loop_ref: + * @loop: a #GMainLoop + * + * Increase the reference count on a #GMainLoop object by one. + * + * Return value: @loop + **/ +GMainLoop * +g_main_loop_ref (GMainLoop *loop) +{ + g_return_val_if_fail (loop != NULL, NULL); + + LOCK_LOOP (loop); + loop->ref_count++; + UNLOCK_LOOP (loop); + + return loop; +} + +static void +main_loop_destroy (GMainLoop *loop) +{ +#ifdef G_THREADS_ENABLED + g_mutex_free (loop->mutex); + if (loop->sem_cond) + g_cond_free (loop->sem_cond); +#endif /* G_THREADS_ENABLED */ + + g_free (loop); +} + +/** + * g_main_loop_unref: + * @loop: a #GMainLoop + * + * Decreases the reference count on a #GMainLoop object by one. If + * the result is zero, free the loop and free all associated memory. + **/ +void +g_main_loop_unref (GMainLoop *loop) +{ + g_return_if_fail (loop != NULL); + g_return_if_fail (loop->ref_count > 0); + + LOCK_LOOP (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. + */ + UNLOCK_LOOP (loop); + main_loop_destroy (loop); + } + else + UNLOCK_LOOP (loop); +} + +/** * g_main_loop_run: * @loop: a #GMainLoop * @@ -2038,11 +2100,16 @@ g_main_loop_run (GMainLoop *loop) { g_return_if_fail (loop != NULL); + /* The assumption here is that a reference is held to the loop + * until we recursively iterate + */ #ifdef G_THREADS_ENABLED if (loop->context->thread != g_thread_self ()) { LOCK_LOOP (loop); + loop->ref_count++; + if (!g_thread_supported ()) { g_warning ("g_main_loop_run() was called from second thread but" @@ -2059,8 +2126,6 @@ g_main_loop_run (GMainLoop *loop) while (loop->is_running) g_cond_wait (loop->sem_cond, loop->mutex); } - - UNLOCK_LOOP (loop); } else #endif /* G_THREADS_ENABLED */ @@ -2076,6 +2141,7 @@ g_main_loop_run (GMainLoop *loop) LOCK_LOOP (loop); + loop->ref_count++; loop->is_running = TRUE; while (loop->is_running) { @@ -2083,8 +2149,19 @@ g_main_loop_run (GMainLoop *loop) g_main_context_iterate (loop->context, TRUE, TRUE); LOCK_LOOP (loop); } + } + + /* We inline this here rather than calling g_main_loop_unref() to + * avoid an extra unlock/lock. + */ + loop->ref_count--; + if (loop->ref_count == 0) + { UNLOCK_LOOP (loop); + main_loop_destroy (loop); } + else + UNLOCK_LOOP (loop); } /** @@ -2116,28 +2193,6 @@ g_main_loop_quit (GMainLoop *loop) } /** - * g_main_loop_destroy: - * @loop: a #GMainLoop - * - * Destroy a #GMainLoop object and free all associated memory. - * The loop must not currently be running via g_main_run(). - **/ -void -g_main_loop_destroy (GMainLoop *loop) -{ - g_return_if_fail (loop != NULL); - g_return_if_fail (!loop->is_running); - -#ifdef G_THREADS_ENABLED - g_mutex_free (loop->mutex); - if (loop->sem_cond) - g_cond_free (loop->sem_cond); -#endif /* G_THREADS_ENABLED */ - - g_free (loop); -} - -/** * g_main_loop_is_running: * @loop: a #GMainLoop. * diff --git a/glib/gmain.h b/glib/gmain.h index dd500c6e8..193876f2f 100644 --- a/glib/gmain.h +++ b/glib/gmain.h @@ -174,7 +174,8 @@ GMainLoop *g_main_loop_new (GMainContext *context, gboolean is_running); void g_main_loop_run (GMainLoop *loop); void g_main_loop_quit (GMainLoop *loop); -void g_main_loop_destroy (GMainLoop *loop); +GMainLoop *g_main_loop_ref (GMainLoop *loop); +void g_main_loop_unref (GMainLoop *loop); gboolean g_main_loop_is_running (GMainLoop *loop); /* GSource: */ @@ -237,7 +238,7 @@ void g_get_current_time (GTimeVal *result); #define g_main_new(is_running) g_main_loop_new (NULL, is_running); #define g_main_run(loop) g_main_loop_run(loop) #define g_main_quit(loop) g_main_loop_quit(loop) -#define g_main_destroy(loop) g_main_loop_destroy(loop) +#define g_main_destroy(loop) g_main_loop_unref(loop) #define g_main_is_running(loop) g_main_loop_is_running(loop) /* Source manipulation by ID */ @@ -131,6 +131,7 @@ struct _GMainLoop { GMainContext *context; gboolean is_running; + guint ref_count; #ifdef G_THREADS_ENABLED GMutex *mutex; @@ -2012,7 +2013,8 @@ g_main_loop_new (GMainContext *context, loop = g_new0 (GMainLoop, 1); loop->context = context; loop->is_running = is_running != FALSE; - + loop->ref_count = 1; + #ifdef G_THREADS_ENABLED if (g_thread_supported ()) loop->mutex = g_mutex_new (); @@ -2025,6 +2027,66 @@ g_main_loop_new (GMainContext *context, } /** + * g_main_loop_ref: + * @loop: a #GMainLoop + * + * Increase the reference count on a #GMainLoop object by one. + * + * Return value: @loop + **/ +GMainLoop * +g_main_loop_ref (GMainLoop *loop) +{ + g_return_val_if_fail (loop != NULL, NULL); + + LOCK_LOOP (loop); + loop->ref_count++; + UNLOCK_LOOP (loop); + + return loop; +} + +static void +main_loop_destroy (GMainLoop *loop) +{ +#ifdef G_THREADS_ENABLED + g_mutex_free (loop->mutex); + if (loop->sem_cond) + g_cond_free (loop->sem_cond); +#endif /* G_THREADS_ENABLED */ + + g_free (loop); +} + +/** + * g_main_loop_unref: + * @loop: a #GMainLoop + * + * Decreases the reference count on a #GMainLoop object by one. If + * the result is zero, free the loop and free all associated memory. + **/ +void +g_main_loop_unref (GMainLoop *loop) +{ + g_return_if_fail (loop != NULL); + g_return_if_fail (loop->ref_count > 0); + + LOCK_LOOP (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. + */ + UNLOCK_LOOP (loop); + main_loop_destroy (loop); + } + else + UNLOCK_LOOP (loop); +} + +/** * g_main_loop_run: * @loop: a #GMainLoop * @@ -2038,11 +2100,16 @@ g_main_loop_run (GMainLoop *loop) { g_return_if_fail (loop != NULL); + /* The assumption here is that a reference is held to the loop + * until we recursively iterate + */ #ifdef G_THREADS_ENABLED if (loop->context->thread != g_thread_self ()) { LOCK_LOOP (loop); + loop->ref_count++; + if (!g_thread_supported ()) { g_warning ("g_main_loop_run() was called from second thread but" @@ -2059,8 +2126,6 @@ g_main_loop_run (GMainLoop *loop) while (loop->is_running) g_cond_wait (loop->sem_cond, loop->mutex); } - - UNLOCK_LOOP (loop); } else #endif /* G_THREADS_ENABLED */ @@ -2076,6 +2141,7 @@ g_main_loop_run (GMainLoop *loop) LOCK_LOOP (loop); + loop->ref_count++; loop->is_running = TRUE; while (loop->is_running) { @@ -2083,8 +2149,19 @@ g_main_loop_run (GMainLoop *loop) g_main_context_iterate (loop->context, TRUE, TRUE); LOCK_LOOP (loop); } + } + + /* We inline this here rather than calling g_main_loop_unref() to + * avoid an extra unlock/lock. + */ + loop->ref_count--; + if (loop->ref_count == 0) + { UNLOCK_LOOP (loop); + main_loop_destroy (loop); } + else + UNLOCK_LOOP (loop); } /** @@ -2116,28 +2193,6 @@ g_main_loop_quit (GMainLoop *loop) } /** - * g_main_loop_destroy: - * @loop: a #GMainLoop - * - * Destroy a #GMainLoop object and free all associated memory. - * The loop must not currently be running via g_main_run(). - **/ -void -g_main_loop_destroy (GMainLoop *loop) -{ - g_return_if_fail (loop != NULL); - g_return_if_fail (!loop->is_running); - -#ifdef G_THREADS_ENABLED - g_mutex_free (loop->mutex); - if (loop->sem_cond) - g_cond_free (loop->sem_cond); -#endif /* G_THREADS_ENABLED */ - - g_free (loop); -} - -/** * g_main_loop_is_running: * @loop: a #GMainLoop. * @@ -174,7 +174,8 @@ GMainLoop *g_main_loop_new (GMainContext *context, gboolean is_running); void g_main_loop_run (GMainLoop *loop); void g_main_loop_quit (GMainLoop *loop); -void g_main_loop_destroy (GMainLoop *loop); +GMainLoop *g_main_loop_ref (GMainLoop *loop); +void g_main_loop_unref (GMainLoop *loop); gboolean g_main_loop_is_running (GMainLoop *loop); /* GSource: */ @@ -237,7 +238,7 @@ void g_get_current_time (GTimeVal *result); #define g_main_new(is_running) g_main_loop_new (NULL, is_running); #define g_main_run(loop) g_main_loop_run(loop) #define g_main_quit(loop) g_main_loop_quit(loop) -#define g_main_destroy(loop) g_main_loop_destroy(loop) +#define g_main_destroy(loop) g_main_loop_unref(loop) #define g_main_is_running(loop) g_main_loop_is_running(loop) /* Source manipulation by ID */ |