python/gcj thread integration
Andi Vajda
andi@osafoundation.org
Mon Feb 2 20:31:00 GMT 2004
I recently got this to work on Mac OS X, Linux and Windows and was wondering
if there are any hidden problems that are likely to bite at a later time.
The problem
-----------
Allow threads created and started by the python runtime to call into gcj
compiled shared libraries at will on Mac OS X, Linux and Windows.
The expected solution
---------------------
Looking at the CNI documentation it seems to imply that a call to
JvAttachCurrentThread(NULL, NULL) is all that is needed to get the thread to
properly function inside java.
This seems to be true on Windows for all threads and on OS X and Linux
(posix threads) for the main thread. On these latter operating systems other
threads immediately crash in JvAttachCurrentThread(NULL, NULL) when the new
java.lang.Thread object is allocated (actually, when the thread's name is
generated, ie when a string is allocated).
The solution that appears to work
---------------------------------
I had to hence find another way to get this to work on OS X and Linux by
reproducing what happens when a thread is created and started from java.
Taking a closer look at boehm-gc's pthread_support.c file I figured out that
if I call GC_start_routine(si) and _Jv_AttachCurrentThread(thread) from the
new python thread just after it started (by overriding python's
threading.Thread.run() method), I got the thread to behave correctly when
inside java and return without crashes or other weird behaviour. To work
around the chicken/egg issue of allocating the new java.lang.Thread instance
from the thread it's going to be attached to I actually use a
java.lang.Thread instance I created ahead of time when the previous thread
was initialized. Apart from the hack of re-defining the start_info
structure privately defined in pthread_support.c this approach is simple
enough and didn't require any changes to the gcj runtimes.
The question
------------
Is this approach likely to work durably or did I just get lucky here ?
Thanks for your feedback !
Andi..
-----------------------------------------------------------------------------
static java::lang::Thread *nextThread;
static void *run(void *pyThread)
{
_Jv_AttachCurrentThread(nextThread);
nextThread = new java::lang::Thread();
return PyObject_CallMethod((PyObject *) pyThread, "run", NULL);
}
void *attachCurrentThread(PyObject *pyThread)
{
struct start_info {
void *(*start_routine)(void *);
void *arg;
unsigned int flags;
unsigned int registered;
} si;
si.registered = 0;
si.start_routine = run;
si.arg = pyThread;
si.flags = 0;
return GC_start_routine(&si);
}
More information about the Java
mailing list