On Thu, 29 Jun 2000, Daniel Wickstrom wrote:
> I've been experimenting with integrating tclblend into aolserver, and
> after looking at the tclblend code, I'm a little puzzled about
> something. In javaCmd.c the variable java declared as type JavaInfo
> and currentEnv are declared as global variables, yet I would think
> that these two variables would be overwritten each time a new thread
> starts up. Am I missing something? I've noticed using of java locks
> throughout the code. Maybe only one thread can be executing c-code at
> any given time? Any insights would be appreciated.
This is an area of ongoing discussion. Check out the online mainling
list archive for the history.
http://www.mail-archive.com/tcljava@scriptics.com/
The startup stuff is kind of tricky because we need to support
two different kinds of loading. Tcl Blend can be loaded from
Tcl, whick will then load the JVM. Tcl Blend can also be loaded
from a JVM, this means Tcl Blend will also need to load up Tcl.
In the case where Tcl Blend is loaded into Tcl, the JavaGetEnv()
method is called and this bit of code is executed.
if (currentEnv != NULL) {
return currentEnv;
}
That should only let you init the global once (minus any
race conditions, which I will cover in a second).
In the case where Tcl and Tcl Blend are loaded into a JVM,
Java_tcl_lang_Interp_create() is the first native method
that gets called.
Java_tcl_lang_Interp_create(
JNIEnv *env, /* Java environment. */
jobject interpObj) /* Handle to Interp object. */
{
jlong lvalue;
Tcl_Interp *interp;
JNIEnv *oldEnv;
int loadedFromJava = (currentEnv == NULL); /* true if Tcl Blend was
loaded into Java */
if (! loadedFromJava) {
PUSH_JAVA_ENV();
}
interp = Tcl_CreateInterp();
if (JavaSetupJava(env, interp) != TCL_OK) {
jclass err = (*env)->FindClass(env, "tcl/lang/TclRuntimeError");
In this case we don't do a Java lock (because that monitor
has not been init'ed yet), and we call JavaSetupJava().
Inside JavaSetupJava() we have some code like this:
if (initialized) {
return TCL_OK;
}
// Setup from inside a JVM
initialized = 1;
return TCL_OK;
So, the globals "initialized" and "currentEnv" should
only get init'ed once. That should work in almost
every case, but we still have some race conditions
to work out. For example, in the unlikely case that
two Interp() objects were created at the exact same
time, one might be half way into the init when
the second one noticed an init had not been done
and started another one.
The unresolved question about the race conditions is
how you are going to do the lock the resource. In the
case where Tcl Blend is loaded into Tcl, you need to
init the JVM before you can use a JVM monitor through
JNI. In the case where Tcl Blend and Tcl are loaded
into a JVM, you could use a Java monitor to do the lock.
The tricky part is how Tcl is compiled. If Tcl is compiled
with threads support enabled, then you could use a Tcl
mutex to protect the resources. Problem is, some people
might not want to use the thread enabled version of Tcl.
I am kind of leaning towards requiring the thread
enabled version of Tcl for Tcl Blend because I think
going for a simple solution and avoiding using JNI when
we can is a very good thing.
We would certainly welcome any suggestions or insights
you might have on the subject. I hope that we can
get all these threading issues ironed out in the next
3-4 weeks so that we can cut a 1.3.0 release of
Jacl and Tcl Blend for people to bang on.
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 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