Re: gdk_threads_enter/leave in 2.[4] [PATCH]



Hi,

Am Do, 2003-08-21 um 11.21 schrieb Michael Meeks:
> 	So - I'm currently trying (with some limited success) to weld together
> the OO.o(VCL) and gtk+ mainloops. This creates some interesting
> problems.
> 
> 	The nastiest problem is that while I can try and create a new
> SolarMutex (VCL's Yield/X/big-global lock) by wrapping the
> gdk_threads_mutex, problems arise since the VCL mutex is a recursive
> one, and the gdk mutex is not.
> 
> 	In many cases this is not so much of a problem; since we  drop the
> recursive mutex when we're about to call g_main_iteration,
> but picking it up again when we know the gdk_ lock is already held - in
> X filter methods etc. is not overly elegant. Some of the mess that this
> creates can be see here:
> 
> 	http://ooo.ximian.com/patches/RC3/gtk-integration.diff
> and	http://ooo.ximian.com/patches/RC3/glib-integration.diff
> 
> 	[ the salinst.cxx code being the main issue ].
> 
> 	So - in an ideal world I'd be able to hook gdk_threads_enter/leave and
> re-direct these into my code which would then be able to do a good job
> of this with a single unified locking scheme that provides both expected
> behaviors.
> 
> 	There are two stumbling blocks to this approach:
> 
> 	* GDK_THREADS_ENTER/LEAVE - these in-line macros code
> 	  the assumption that we have a GMutex * to call 
> 	  g_mutex_[un]lock on into all user code.
> 
> 	* gdk_threads_enter/leave are not hookable.
> 
> 	So; assuming I hit some insuperable obstacle with my current
> machinations [ which seems likely ] the only real solution at my
> disposal is pure evil: provide a replacement gthread method table, and
> special case g_mutex_lock (lock == gdk_threads_mutex) - a rather
> undesirable solution.
> 
> 	Alternatively, we could (perhaps) fix this up in gtk+ like this. If
> this is interesting to people, I'd be most happy to hack it up
> forthwith:
> 
> 	+ typedef void (*GdkLockUnlockFn) (void);
> 	+ extern GdkLockUnlockFn gdk_threads_lock;
> 	+ extern GdkLockUnlockFn gdk_threads_unlock;
> 
> #define GDK_THREADS_ENTER() \
> 	if (gdk_threads_lock) \
> 		gdk_threads_unlock ();
> ...
> 
> 	where gdk_threads_lock/unlock point at enter/leave in threaded mode,
> but NULL in non-threaded mode.
> 
> 	In the non-threaded case we loose nothing, and in the threaded case, we
> get an extra stack frame of gdk_threads_enter -> g_thread_lock; and
> perhaps an extra check in gdk_threads_enter/leave.

Here's a translation from prose to code. It's also in bugzilla,

http://bugzilla.gnome.org/show_bug.cgi?id=122448

It would really help OOo/Gtk+ integration to have this in Gtk+ 2.4

Comments?

Thanks,
	Martin
cvs server: Diffing .
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.4493
diff -u -r1.4493 ChangeLog
--- ChangeLog	15 Sep 2003 22:21:18 -0000	1.4493
+++ ChangeLog	16 Sep 2003 14:11:48 -0000
@@ -1,3 +1,20 @@
+Tue Sep 16 15:46:31  Martin Kretzschmar  <m_kretzschmar gmx net>
+
+	* gdk/gdk.h: new gdk_threads_lock, gdk_threads_unlock, point to
+	implementation of GDK_THREADS_ENTER / GDK_THREADS_LEAVE.
+	(GDK_THREADS_ENTER, GDK_THREADS_LEAVE): use gdk_threads_[un]lock
+	function pointers.
+	Add /* private */ comment to gdk_threads_mutex.
+	
+	* gdk/gdk.c (gdk_threads_impl_lock, gdk_threads_impl_unlock): new,
+	extracted from GTK_THREADS_ENTER/LEAVE macros.
+	(gdk_threads_init): init gtk_threads_[un]lock.
+
+	* gdk/gdkglobals.c: add definitions of gdk_threads_[un]lock.
+
+	* gdk/gdktypes.h: new GdkLockUnlockFn typedef for
+	gdk_threads_[un]lock.
+
 2003-09-16  Matthias Clasen  <maclas gmx de>
 
 	* gtk/gtkaction.h: Apply egtk-format-protos.
cvs server: Diffing gdk
Index: gdk/gdk.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdk.c,v
retrieving revision 1.151
diff -u -r1.151 gdk.c
--- gdk/gdk.c	16 Aug 2003 14:43:59 -0000	1.151
+++ gdk/gdk.c	16 Sep 2003 14:11:51 -0000
@@ -494,6 +494,20 @@
   GDK_THREADS_LEAVE ();
 }
 
+static void
+gdk_threads_impl_lock ()
+{
+  if (gdk_threads_mutex)
+    g_mutex_lock (gdk_threads_mutex);
+}
+
+static void
+gdk_threads_impl_unlock ()
+{
+  if (gdk_threads_mutex)
+    g_mutex_unlock (gdk_threads_mutex);
+}
+
 /**
  * gdk_threads_init:
  * 
@@ -511,6 +525,8 @@
     g_error ("g_thread_init() must be called before gdk_threads_init()");
 
   gdk_threads_mutex = g_mutex_new ();
+  gdk_threads_lock = gdk_threads_impl_lock;
+  gdk_threads_unlock = gdk_threads_impl_unlock;
 }
 
 G_CONST_RETURN char *
Index: gdk/gdk.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdk.h,v
retrieving revision 1.100
diff -u -r1.100 gdk.h
--- gdk/gdk.h	31 Jan 2003 00:08:32 -0000	1.100
+++ gdk/gdk.h	16 Sep 2003 14:11:52 -0000
@@ -171,7 +171,10 @@
 /* Threading
  */
 
-GDKVAR GMutex *gdk_threads_mutex;
+/* private */ GDKVAR GMutex *gdk_threads_mutex;
+
+GDKVAR GdkLockUnlockFn gdk_threads_lock;
+GDKVAR GdkLockUnlockFn gdk_threads_unlock;
 
 void     gdk_threads_enter                (void);
 void     gdk_threads_leave                (void);
@@ -179,12 +182,12 @@
 
 #ifdef	G_THREADS_ENABLED
 #  define GDK_THREADS_ENTER()	G_STMT_START {	\
-      if (gdk_threads_mutex)                 	\
-        g_mutex_lock (gdk_threads_mutex);   	\
+      if (gdk_threads_lock)                 	\
+        gdk_threads_lock ();			\
    } G_STMT_END
 #  define GDK_THREADS_LEAVE()	G_STMT_START { 	\
-      if (gdk_threads_mutex)                 	\
-        g_mutex_unlock (gdk_threads_mutex); 	\
+      if (gdk_threads_unlock)                 	\
+        gdk_threads_unlock ();			\
    } G_STMT_END
 #else	/* !G_THREADS_ENABLED */
 #  define GDK_THREADS_ENTER()
Index: gdk/gdkglobals.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkglobals.c,v
retrieving revision 1.28
diff -u -r1.28 gdkglobals.c
--- gdk/gdkglobals.c	31 Oct 2002 21:11:13 -0000	1.28
+++ gdk/gdkglobals.c	16 Sep 2003 14:11:52 -0000
@@ -40,5 +40,6 @@
 
 GSList             *_gdk_displays = NULL;
 
-GMutex           *gdk_threads_mutex = NULL;          /* Global GDK lock */
-
+GMutex              *gdk_threads_mutex = NULL;          /* Global GDK lock */
+GdkLockUnlockFn      gdk_threads_lock = NULL;
+GdkLockUnlockFn      gdk_threads_unlock = NULL;
Index: gdk/gdktypes.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdktypes.h,v
retrieving revision 1.63
diff -u -r1.63 gdktypes.h
--- gdk/gdktypes.h	25 Apr 2002 22:29:10 -0000	1.63
+++ gdk/gdktypes.h	16 Sep 2003 14:11:52 -0000
@@ -200,6 +200,8 @@
   gint width;
 };
 
+typedef void (*GdkLockUnlockFn) (void);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */


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