CNI invocation API proposal

Jeff Sturm jsturm@one-point.com
Tue Apr 17 13:06:00 GMT 2001


On Tue, 17 Apr 2001, [iso-8859-1] Joerg Brunsmann wrote:
> Ok, main_init() will be executed only once when the JavaVM is
> created.

Right.  JvRunMain perhaps is not a good example because it
performs numerous one-time initialization tasks.  Signal handlers are
installed by main_init(), this could be moved to a "create VM" function.
(The original handlers should probably be saved here, and restored
if there were a "destroy VM" function.)

> Then the main_thread is created and started which
> waits for termination of all other threads.

Not quite... main_thread executes the Java main(), while the primordial
thread (which called JvRunMain) waits for termination of all other
threads.

> How would you foresee a method which registers the calling
> thread, runs a callback and unregiester itself?

Suppose we name it `JvInvoke', and we have internal methods named
`_Jv_Attach' and `_Jv_Detach' to attach/detach the running thread:

// Invoke a method, attaching myself if needed.  Returns any exception
// thrown by method, or NULL if no exception was thrown.
jthrowable
JvInvoke (jclass clss, jmethodID meth, jobject arg)
{
  _Jv_Thread_t thrd = NULL;
  jthrowable ex;

  // Attach only once.
  if (!_Jv_IsAttached ())
    thrd = _Jv_Attach ();

  // Make sure clss is initialized.
  JvInitClass (clss);

  // Assume meth is a static method, and takes one argument.
  try
    {
      (meth->ncode) (arg);
    }
  catch (jthrowable t)
    {
      ex = t;
    }

  if (thrd)
    _Jv_Detach ();

  return ex;
}

That's far from complete though.  I'm starting to dislike this callback
approach.  Callbacks are clumsy to implement, partly due to argument
processing.  Besides, Cedric Berger raised some valid performance
questions.  So I'm thinking about alternatives.

Another idea is to implement both JvAttach and JvDetach, in which JvDetach
will perform a longjmp() to the attach point.  Below is a hypothetical 
example which attempts to create and start a Thread object:

  if (JvAttach ())
    {
      try
        {
          jclass cls = java::lang::Class::forName ("...");
          jobject obj = cls->newInstance ();
          if (_Jv_IsInstanceOf (obj, java::lang::Thread::class$))
            ((jthread) obj)->start ();
        }
      catch (jthrowable t)
        {
        }
      JvDetach ();
    }

Normally JvAttach would return a Thread instance corresponding to the
invoking thread (it may do nothing if the calling thread is attached).
JvDetach would perform a longjmp, causing JvAttach to return NULL.  It
would be possible for a native thread to attach once and never detach if
desired.
 
> > >     3. Is it possible and reasonable to build a JNI based 
> > >        invocation interface upon the CNI based approach?
> > 
> > I think so, provided you can safely implement attach/detach and
> > dynamically load the VM (i.e. dlload libgcj.so).
> 
> Do you anticipate high hurdles while realising this approach?

To be honest I'm not closely familiar with the JNI implementation.
Some of the comments in jni.cc suggest there is certain behavior that will
be difficult to get exactly right.

It seems as though JNI assumes a thread can have different stacks
for native code and java code.  That makes it well suited for interpreted
VMs, in which the java stack can be manipulated in a portable way.  I
suspect it would be a challenge to get 
AttachCurrentThread/DetachCurrentThread exactly right for gcj.

Jeff




More information about the Java mailing list