D called from Java
Sean Kelly
sean at f4.ca
Sun Aug 19 08:20:05 PDT 2007
Frank Benoit wrote:
> Sean Kelly schrieb:
>> Tango will have this once I have time for it. Likely not long after the
>> conference :-)
>
> The more i think about it, how will it work?
>
> The d runtime (drt) needs to know all running threads, for the following
> reason:
> * be able to stop all threads while the GC is running
> * provide a thread local storage container.
> * synchronization?
The user would call some routine from each thread he wants to register,
or perhaps simply pass the thread id. The threads would have to be
de-registered when they terminate as well.
> But does the drt also need to know about the termination of a thread?
Yes. It may be possible to get away without explicitly notifying the GC
of thread termination on Windows, based on how that code works, but on
Unix I think such notification is necessary.
> If so, the registration must be paired with a deregistration on each
> library entry point. This also means, register and deregister need to be
> really fast because they are called every time the lib is entered or left.
The registration would involve a memory allocation for the proxy thread
object and a mutex lock to place it in a list.
> export extern(System)
> jint Java_test_Test_test( JNIEnv* env, jobject obj ) {
> Thread.register();
> scope( exit ) Thread.deregister();
> // ...
> }
>
> In the scenario, were the D GC is actually running and has all known
> threads suspended, the Thread.register() call needs to block until the
> GC completes. Probably the methods are better called like enterD/leaveD.
I /think/ the only risk of being blocked by the GC will be allocating
the proxy thread object. It should be okay if a GC cycle is running
after this time when the object is enlisted, though it would mean an
attempted resume on a running thread. This should work fine given how
things are implemented, but I'll have to see if I can test it somehow to
be sure.
> export extern(System)
> jint Java_test_Test_test( JNIEnv* env, jobject obj ) {
> Thread.enterD();
> scope( exit ) Thread.leaveD();
> // ...
> }
>
> Hopefully this will not raise some new deadlock conditions.
> 1. D ctor remove held Java global references
> 2. this removal triggers the Java finalizer
> 3. another java object.finalize calls therefore the D lib, to signal the
> end of the javas object lifecycle.
> 4. the call blocks and the dtor call from (1) does not return.
If the D GC is running then all threads it knows about will be suspended
until the collection completes. The mutex guarding memory allocations
will be locked as well. So operations in D object dtors must consider
this. It's possible to deadlock even without this Java integration if
an attempt is made to enter a synchronized block that may already be
held by a suspended thread. In fact, this is why Tango does not have
notifyRegister--using the routine to unregister a slot could easily
deadlock for this exact reason.
Sean
More information about the Digitalmars-d
mailing list