On Sat, 21 Oct 2000, Dan Wickstrom wrote:

> >
> > What does your src/tclblend/tcl/lang/CObject.java finalize()
> > method look like? I thought the last round of patches left
> > that ptr dangling on purpose. I have not has time to
> 
> Yes the finalize method just calls the super class finalize method.

Well, that would be your memory leak :)

> > look at the patches your guys are using so I am not
> > sure what is going on. I think what we need to do in the
> > short term is to implement a patch that will send a
> > Tcl_Obj that gets freed back to the Tcl interp using
> > the thread safe event queue.
> 
> Are you talking about having the CObject finalize method put a reference to the
> Tcl_Obj into the notifier queue for the thread that created the Tcl_obj, and
> then have the Tcl_Obj cleaned up when the event is queued?

Yes. The tricky part is going to be changing the C code to support
this. We are going to need to have the ability to enque a TclEvent
in the GC thread, but we need an interp handle for that.

Here is that I am currently looking into:

A CObject() is created by calling
newInstance() from JNI code.
But, we don't have a handle to
an interp in the calling code.

We need to wrap this into an
object along with the interp
handle and put it into a table
somewhere so that the wrapped
object can not get GCed.

class CObjectCleanupTable {
  static void addObjRef(Interp i, long ptr)
  static void deleteObjRef(long ptr)
  static void finalizeObjRef(long ptr)
}

It seems like we could change the
CObject.newInstance() signature, so
that the Interp object would need
to get passed along too.

(Old)

private static TclObject
newInstance(
    long objPtr)                // Tcl_Obj to wrap.
{
    return new TclObject(new CObject(objPtr));
}


(New)

private static TclObject
newInstance(
    Interp interp,              // Current Interp
    long objPtr)                // Tcl_Obj to wrap.
{
    return new TclObject(new CObject(interp, objPtr));
}

This means that any place where CObject.newInstance()
(only JavaGetTclObject at this point) is called would
also need to include the Interp parameter.

Now the CObject ctor could register the given objPtr
like so:

CObject(
    Interp interp,              // The current Interp
    long objPtr)                // Pointer to Tcl_Obj from C.
{
    this.objPtr = objPtr;
    incrRefCount(objPtr);
    CObjectCleanupTable.addObjRef(interp, objPtr);
}


Then in the finalize method we would do this:

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*.
         */

        CObjectCleanupTable.finalizeObjRef(objPtr);
    }
    super.finalize();
}


That would enqueue a TclEvent that would end up calling
CObject.decrRefCount(objPtr) inside the thread where
the Tcl_Obj was created.

I think it is doable, but some hacking is going to
be required.


> > We also need to make the Tcl Blend Notifier thread
> > safe. I think time would be better spent focusing
> > on that right now instead of fighting ref counting.
> 
> Is this just a matter of modifying the Notifier class so that there
> is an event queue per thread instead of a global queue as there
> is now.  Are there any modifications necessary in the 'c' code?

Making the Notifier "thread safe" is actually the easy part.
All you would need to do is add another field to the Java
interp structure that would store the "Tcl Thread ID" value.
You would get the thread id in the pkg init code, and then save
it into the Interp structure.

ThreadID curThread;
GetCurrentThread(&curThread);
/* put into interp field */


This TclThreadID is needed so that you can call the
Tcl_ThreadAlert(ThreadID) from inside the Notifier
code.

Once that bit is in place, you would then need to
rip out the current notifier implementation.
Start with the Jacl impl of Notifier and
copy it into the Tcl Blend dir. Now merge any
diffs over from the Tcl Blend impl but leave
out all of the "global notifier" crap. The
only thing to watch out for is to keep
Jiang's fixed for deadlocking in the
Notifier queue. I don't think that
patch ever made it into Jacl so
don't copy that bit (see ChangeLog
entry on 2000-08-23).

Now it is just a matter of going in a deleting
all the unused C code that was used to implement
the old notifier. That part should be fun cause
there is just a gob of nasty code in there and
one quick press of the delete button will finish
it off.

Are you up to it? I am going to be working on
this object ref queue thing for some time, 
so if you could take a whack at the Notifier
it would really help. There is not going to
be much overlap in these changes, so they
can be done in parallel.

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

Reply via email to