missing GMainContext methods ...



So,

	I sent this a while back - but didn't see it on the list - perhaps
broken subscription information (?).

	I append a patch implementing these two to some level.

On Thu, 2005-11-17 at 16:57 +0000, michael meeks wrote:
> 	So - I've been trying to use the GMainContext to fix a rather tricky
> issue in using unsafe single-threaded code accessed via ORBit2 from
> multiple OO.o threads in a safe & reliable way. This is somewhat
> involved, for various reasons, but made particularly unpleasant due to 2
> missing methods:
> 
> 	a) gboolean g_main_context_is_owner (GMainContext *context);
> 		+ this would tell you if the current thread owns the
> 		  g_main_context. NB. this is subtly different from
> 		  something like:
> 			if (g_main_context_acquire ()) {
> 				g_main_context_release();
> 				... I own it - horay ...
> 			}
> 		+ since that actually transiently takes ownership of
> 		  the thread but doesn't tell you if you (now) contine
> 		  to own it [ due to some (much) higher stack frame
> 		  having taken that lock ].
> 
> 	b) void g_main_context_acquire_with_wakeup (GMainContext *context);
> 		+ this cunning method - would be the analogue of
> 		  g_main_context_wait () - except instead of sitting
> 		  around hoping that the other thread doing the poll
> 		  will wake-up, it does a (safe) g_main_context_wakeup
> 		  with the relevant locks held;
> 		+ currently it appears impossible/acutely-ugly to
> 		  get ownership of the GMainContext from another thread
> 		  if the main thread is in it's poll.
> 
> 	The basic reasoning here is that - ~all existing event-driven gtk+
> code, typically happens from the default GMainContext, and/or at least
> that provides a reasonable back-compatible way to create a backwards
> compatible 'apartment' (by holding the GMainContext lock) to execute old
> code in in-line.

	I attach a simple patch; the g_main_context_is_owner impl. is of course
trivial - it'd be great to be able to commit that by itself. The
'acquire_with_wakeup' is also relatively trivial, cf. above.

	There is no bugzilla number, is that a problem ?

	Thanks,

		Michael.

-- 
 michael meeks novell com  <><, Pseudo Engineer, itinerant idiot
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/glib/ChangeLog,v
retrieving revision 1.2174
diff -u -p -u -r1.2174 ChangeLog
--- ChangeLog	18 Dec 2005 02:46:26 -0000	1.2174
+++ ChangeLog	20 Dec 2005 17:16:22 -0000
@@ -1,3 +1,12 @@
+2005-12-20  Michael Meeks  <michael meeks novell com>
+
+	* glib/gmain.c (g_main_context_is_owner): determine if
+	the current thread is the owner of the context.
+	(g_main_context_acquire_with_wakeup):
+	implement - contrasting with g_main_context_wait - this
+	actually atomically wakes the (potentially blocking &
+	unresponsive) context on which we are waiting.
+
 2005-12-17  Matthias Clasen  <mclasen redhat com>
 
 	* glib/goption.c (parse_short_option): Set an error in all
Index: glib/gmain.c
===================================================================
RCS file: /cvs/gnome/glib/glib/gmain.c,v
retrieving revision 1.135
diff -u -p -u -r1.135 gmain.c
--- glib/gmain.c	5 Dec 2005 15:01:26 -0000	1.135
+++ glib/gmain.c	20 Dec 2005 17:16:22 -0000
@@ -3156,6 +3156,63 @@ g_main_context_wakeup (GMainContext *con
   UNLOCK_CONTEXT (context);
 }
 
+/**
+ * g_main_context_is_owner:
+ * @context: a #GMainContext
+ * 
+ * If the current thread is the owner of @context returns
+ * TRUE else FALSE. This is semantically rather different
+ * from acquiring ownership.
+ *
+ * Returns: TRUE if current thread is owner of @context.
+ **/
+gboolean
+g_main_context_is_owner (GMainContext *context)
+{
+  gboolean is_owner;
+
+  if (!context)
+    context = g_main_context_default ();
+
+#ifdef G_THREADS_ENABLED
+  LOCK_CONTEXT (context);
+  is_owner = context->owner == G_THREAD_SELF;
+  UNLOCK_CONTEXT (context);
+#else
+  is_owner = TRUE;
+#endif
+
+  return is_owner;
+}
+
+/**
+ * g_main_context_acquire_with_wakeup:
+ * @context: a #GMainContext
+ * 
+ * This method tries to acquire the context, and if the
+ * context is owned by another thread - wakes that thread
+ * to get it to release ownership.
+ **/
+void
+g_main_context_acquire_with_wakeup (GMainContext *context)
+{
+  gboolean got_ownership;
+
+  if (!context)
+    context = g_main_context_default ();
+
+  got_ownership = g_main_context_acquire (context);
+  while (!got_ownership)
+    {
+      LOCK_CONTEXT (context);
+      g_main_context_wakeup_unlocked (context);
+      got_ownership = g_main_context_wait (context,
+					   context->cond,
+					   g_static_mutex_get_mutex (&context->mutex));
+      UNLOCK_CONTEXT (context);
+    }
+}
+
 /* Timeouts */
 
 static void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]