Re: gdk_threads_enter/leave in 2.[4] [PATCH]
- From: Martin Kretzschmar <m_kretzschmar gmx net>
- To: Gtk Hackers <gtk-devel-list gnome org>
- Cc: Owen Taylor <otaylor redhat com>, Federico Mena-Quintero <federico ximian com>, Michael Meeks <michael ximian com>
- Subject: Re: gdk_threads_enter/leave in 2.[4] [PATCH]
- Date: Tue, 16 Sep 2003 16:43:53 +0200
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]