[Tcl Java] Re: [Tcl Java] RE: [Tcl Java] Re: [Tcl Java] what I now know about the deadlock

2000-06-15 Thread Mo DeJong

On Wed, 14 Jun 2000, W. John Guineau wrote:

> Without having looked into the innerds of TclBlend's JNI implementation
> (though it looks quite clean at least) I'd say that removing the monitor
> calls and JAVA_LOCK are probably fine.
> 
> I say this because we have a decent size app (~250K lines of C/C++/Java)
> that uses a JNI layer I wrote. I never use locking in the JNI layer (in
> general) and have multithreaded access without any apparent problems (the
> JNI part is the backend of a Java based server that provides access to
> common C code.)



I am still a bit worried about the gc thread walking around
in the Tcl interp at any random time.


>From the deadlock problem report.

3) The sequence of events leading up to deadlock is the following:

a) the main thread calls MonitorExit in JavaCmdProc
b) the garbage collection thread calls MonitorExit in JavaCmdDeleteProc
c) the garbage collection thread calls MonitorEnter in JavaCmdDeleteProc
d) the main thread calls MonitorEnter in JavaCmdProc (and blocks)


>From JavaCmdProc():

/*
 * Invoke the command by calling Interp.callCommand().  Be sure to
 * leave the monitor since we are assuming nothing about the state
 * of the world after this call.
 */

JAVA_UNLOCK();
result = (*env)->CallIntMethod(env, interpObj,
java.callCommand, cmd, args);
exception = (*env)->ExceptionOccurred(env);
JAVA_LOCK();



Inside Java_tcl_lang_Interp_createCommand, we tell the Tcl command
to call JavaCmdDeleteProc when it gets deleted:


   Tcl_CreateObjCommand(interp, (/*UNCONST*/ char *) name, JavaCmdProc,
(ClientData) cmd, JavaCmdDeleteProc);



This calls interface CommandWithDispose.dispose() method:

static void
JavaCmdDeleteProc(
ClientData clientData)
{
jobject cmd = (jobject)clientData;
JNIEnv *env = JavaGetEnv(NULL);

if ((*env)->IsInstanceOf(env, cmd, java.CommandWithDispose)) {
/*
 * We need to release the monitor while running arbitrary Java code.
 */

JAVA_UNLOCK();
(*env)->CallVoidMethod(env, cmd, java.disposeCmd);
JAVA_LOCK();
}
(*env)->DeleteGlobalRef(env, (jobject)clientData);
}



It seems like the call to JavaCmdDeleteProc() in the GC thread
would not need to unlock anything because it did not have the
monitor in the first place, it was released before calling
the Java method in JavaCmdProc(). Also, this seems
to only happen in the wacky case where the command we
are invoking is getting deleted from the interp, I am
not sure why this has never come up before, perhaps is
is a race condition or the Sun GC thread is running
earlier than it did before.


I did a detailed trace of how JavaCmdDeleteProc() would be
called by the GC thread (I could not figure out how that
would ever happen at first).


We start at the CObject.finalize() method, which is getting
called by the GC thread.

/* Clean up the native Tcl_Obj when a CObject is collected. */

protected void finalize() throws Throwable
{
if (objPtr != 0) {
/*
 * If the object is finalized while the reference is still valid, 
 * we need to sever the connection to the underlying Tcl_Obj*.
 */

decrRefCount(objPtr);
}
super.finalize();
}


That calls CObject.decrRefCount() which is implemented in
the native method Java_tcl_lang_CObject_decrRefCount.
This native method then calls Tcl_DecrRefCount().

Then, a bunch of calls into Tcl and Java:

Tcl_DecrRefCount() -> TclFreeObj() -> freeIntRepProc() ->
FreeJavaCmdInternalRep() -> FreeTclObject() -> TclObject.release() ->
InternalRep.dispose() -> ReflectObject.dispose() ->
Interp.deleteCommand() -> Java_tcl_lang_Interp_deleteCommand() ->
Tcl_DeleteCommand() -> Tcl_DeleteCommandFromToken() -> JavaCmdDeleteProc()


So finally, after all that, we know how to GC thread ended up
calling JavaCmdDeleteProc().


The real question here is what should we do about the GC thread?
Should we have a lock for each interp that will need to be grabbed
by the interp thread or the GC thread before the internals of
the Interp can be accessed? It would be a real drag if every Tcl
event needed to grab a global GC monitor before the event could
be processed.

I don't think we really want to halt the GC thread for long periods
of time waiting for the Interp to get done doing something. This
is what would happen if put an event into the Tcl event queue
and made the GC thread block until the event was processed.

This is kind of wacky because in the case where Tcl is not compiled with 
threads enabled, we could still have a GC thread knocking on the door.
Perhaps we should just require Tcl compiled with thread support.

Mo DeJong
Red Hat Inc


The TclJava mailing list is sponsored by Scriptics Corporation.
To subscribe:send mail to [EMAIL PROTECTED]  
 with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to [EMAIL P

[Tcl Java] RE: [Tcl Java] Re: [Tcl Java] what I now know about the deadlock

2000-06-14 Thread W. John Guineau


Without having looked into the innerds of TclBlend's JNI implementation
(though it looks quite clean at least) I'd say that removing the monitor
calls and JAVA_LOCK are probably fine.

I say this because we have a decent size app (~250K lines of C/C++/Java)
that uses a JNI layer I wrote. I never use locking in the JNI layer (in
general) and have multithreaded access without any apparent problems (the
JNI part is the backend of a Java based server that provides access to
common C code.)

john

> -Original Message-
> From: Dr Wes Munsil [mailto:[EMAIL PROTECTED]]
> Sent: Wednesday, June 14, 2000 7:40 AM
> To: [EMAIL PROTECTED]
> Subject: [Tcl Java] Re: [Tcl Java] what I now know about the deadlock
>
>
> I hope you will tell me "SOLUTION 1, and Tclblend_Init doesn't
> matter  in this
> context," because that seems to fix my problem.
>
> Dr Wes Munsil wrote:
>
> > Please give me your advice.
> >
> > I've instrumented TclBlend to look for the pattern of execution of
> > MonitorEnter/MonitorExit calls and have learned this. The deadlock seen
> > in my code, and now in the TclBlend regression test
> > AutomaticSignature.test on Solaris with native threads, has these
> > characteristics:
> >
> > 1) Tclblend_Init is never called. Consequently the call of MonitorEnter
> > in that function is never executed.
> >
> > 2) Although Jiang's patch removes the MonitorEnter and MonitorExit calls
> > from JAVA_LOCK and JAVA_UNLOCK, there are still other calls of
> > MonitorEnter and MonitorExit: they occur in Exit/Enter pairs in
> > JavaIdleProc, JavaTraceProc, JavaCmdDeleteProc, JavaCmdProc,
> > JavaEventProc, and JavaTimerProc.
> >
> > 3) The sequence of events leading up to deadlock is the following:
> >
> > a) the main thread calls MonitorExit in JavaCmdProc
> > b) the garbage collection thread calls MonitorExit in JavaCmdDeleteProc
> > c) the garbage collection thread calls MonitorEnter in JavaCmdDeleteProc
> >
> > d) the main thread calls MonitorEnter in JavaCmdProc (and blocks)
> >
> > I can think of two solutions to this problem, but I don't know which is
> > "right."
> >
> > SOLUTION 1. Simply remove all remaining calls of MonitorEnter and
> > MonitorExit.
> > SOLUTION 2. Replace all remaining calls of MonitorEnter and MonitorExit
> > by invocations of JAVA_LOCK and JAVA_UNLOCK, respectively (which now
> > have the MonitorEnter and MonitorExit calls removed, but which retain
> > the fiddling with the Java environment).
> >
> > In either case, we should possibly discover why Tclblend_Init is not
> > being called, and fix that.
> >
> > What do you think?
> >
> > Thank you.
> >
> > 
> > The TclJava mailing list is sponsored by Scriptics Corporation.
> > To subscribe:send mail to [EMAIL PROTECTED]
> >  with the word SUBSCRIBE as the subject.
> > To unsubscribe:  send mail to [EMAIL PROTECTED]
> >  with the word UNSUBSCRIBE as the subject.
> > To send to the list, send email to '[EMAIL PROTECTED]'.
> > An archive is available at
> http://www.mail-archive.com/tcljava@scriptics.com
>
>
> 
> The TclJava mailing list is sponsored by Scriptics Corporation.
> To subscribe:send mail to [EMAIL PROTECTED]
>  with the word SUBSCRIBE as the subject.
> To unsubscribe:  send mail to [EMAIL PROTECTED]
>  with the word UNSUBSCRIBE as the subject.
> To send to the list, send email to '[EMAIL PROTECTED]'.
> An archive is available at
> http://www.mail-archive.com/tcljava@scriptics.com
>
>


The TclJava mailing list is sponsored by Scriptics Corporation.
To subscribe:send mail to [EMAIL PROTECTED]  
 with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to [EMAIL PROTECTED] 
 with the word UNSUBSCRIBE as the subject.
To send to the list, send email to '[EMAIL PROTECTED]'. 
An archive is available at http://www.mail-archive.com/tcljava@scriptics.com