Gtk2+ and thread safety



Hi,

We are working on a Java peer set for gtk at Sun. We have it pretty much finished apart from a few bugs which are mostly due to missing features in Gtk 1.2. It was our original intention to use Gtk+ 1.2 but we are investigating the possibility of migrating it to 2.0 to fix the bugs due to missing features in 1.2. I have ported the code to the new 2.0 library but we are now experiencing many thread synchronization problems. I have read the threading documentation but it does not appear there is anything extra that we have to do (apart from calling gdk_threads_init as well as g_threads_init). The code worked fine under 1.2 but is failing nearly all the time on 2.0.

The problem seems to be due to the main event queue not blocking other threads when processing callbacks. Under the debugger I have found that one thread has called gdk_threads_enter yet the main event loop still calls a callback and hence multiple thrtead access to the Gtk library and we get X async errors. It is as though the gdk_threads_enter does not block the main loop. I am wondering if I need to configure the library in some way to enable thread support. Perhaps the documentation hasn't been updated for writing multi threaded programs in Gtk2.0? Does anyone know if there are any major changes in this area?

Because gdk_threads_enter is not guarenteed to be recursive (this would be sooo nice if it were!) we have written our own utility functions for thread locking that provide recursive features. We assume we will be using pthreads as we are only based on Linux currently and this little hack seems to work. It is a hack as we assume that pthread_self never returns 0 (which it never seems to under Linux). Our utility functions look like this:

static int lockCount = 0;
static pthread_t lockOwner = 0;

void
awt_gtk_threadsEnter(void)
{
   pthread_t self = pthread_self();
if (self != lockOwner)
   {
       gdk_threads_enter();
       lockOwner = self;
       lockCount = 1;
   }
else lockCount++;
}

void
awt_gtk_threadsLeave(void)
{
   pthread_t self = pthread_self();
assert (self == lockOwner); lockCount--; assert (lockCount >= 0); if (lockCount == 0)
   {
       lockOwner = 0;
       gdk_threads_leave();
   }
}


void
awt_gtk_callbackEnter(void)
{
   if (lockOwner == 0)
       lockOwner = pthread_self();
assert (lockOwner == pthread_self()); lockCount++;
}

void
awt_gtk_callbackLeave(void)
{
   lockCount--;
assert (lockCount >= 0); if (lockCount == 0)
       lockOwner = 0;
}

We have two sets of locking functions: one for use in callbacks (as we don't want to call gdk_threads_enter here as the main loop should already have the mutex lock) and one for use in other threads.

Does anyone have any idea what we could be doing wrong? The code works fine on Gtk1.2 and there appears to be 
no changes needed from the documentation.

Thanks for any help anyone can offer...

--
Nick Allen
Software Engineer
Sun Microsystems Ireland Ltd
Hamilton House
East Point Business Park
Dublin 3

email: nicholas allen ireland sun com

The views expressed in this email are not necessarily the views of Sun Microsystems or its staff





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