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