summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2001-01-03 20:18:40 +0000
committerOwen Taylor <otaylor@src.gnome.org>2001-01-03 20:18:40 +0000
commit3ae4c59e3f9a155436970a7d97d64676178a709c (patch)
tree0669482a20afe700bc0317eb2649aefc69d18619
parentb1d840c20a27dd756bd7bd5877631cb8acae1c62 (diff)
Switch GMainLoop to be ref/unref, use to make dropping reference to
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.
-rw-r--r--ChangeLog7
-rw-r--r--ChangeLog.pre-2-07
-rw-r--r--ChangeLog.pre-2-107
-rw-r--r--ChangeLog.pre-2-127
-rw-r--r--ChangeLog.pre-2-27
-rw-r--r--ChangeLog.pre-2-47
-rw-r--r--ChangeLog.pre-2-67
-rw-r--r--ChangeLog.pre-2-87
-rw-r--r--glib/gmain.c105
-rw-r--r--glib/gmain.h5
-rw-r--r--gmain.c105
-rw-r--r--gmain.h5
12 files changed, 214 insertions, 62 deletions
diff --git a/ChangeLog b/ChangeLog
index 32fd7d2be..a8fbd0000 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 */
diff --git a/gmain.c b/gmain.c
index 61957e213..29af3b0e7 100644
--- a/gmain.c
+++ b/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/gmain.h b/gmain.h
index dd500c6e8..193876f2f 100644
--- a/gmain.h
+++ b/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 */