I tried Mo's patch on CObject.finalize() to see if any TclBlend code will
leak C objects. And it does. There are a number of places in the "tcljava"
code that do:
TclList.index(interp,list,0).toString();
This will cause a CObject to be garbage collected without first releasing
the native Tcl_Obj. Does anyone has any opinion as to how we should go
about fixing these? We can make all those instance of
TclList.index(...).toString() into:
TclObject listElement = TclList.index(...);
listElement.preserve();
listElement.toString();
listElement.release();
Or we can try to fix the CObject finalize. I propose something like this:
1. In CObject.finalize(), add any pointer to Tcl_Obj to a global
Vector. Then create and queue a TclEvent.
2. Inside the TclEvent, free all Tcl_Obj on the global Vector using
the Tcl interpreter thread.
My problem with the above approach is that the user of TclBlend must
register a Interp object to be used to perform the freeing of the Tcl_Obj.
Here is some pseudo code to do the above:
class CObject {
protected void finalize() throws Throwable
{
if (objPtr != 0) {
addToFreeList(objPtr);
}
super.finalize();
}
// a vector of Tcl_Obj pointers to be free'ed
private static Vector freeTclObjPtrs = new Vector();
// a lock object to synchronize access to the 'freeTclObjPtr'.
private static Object freeTclObjPtrsLock = new Object();
/*
* Add a pointer to the to be free'ed vector. The CObject containing
* this pointer is being finalized by the GC. This method is only
* called by 'CObject.finalize()'. This method is thread safe.
*/
private static void addToFreeList (long objPtr) {
synchronized (freeTclObjPtrsLock) {
freeTclObjPtrs.addElement(new Long(objPtr));
// create and queue a TclEvent, to be completed
}
}
/*
* This method makes a copy of the existing 'freeTclObjPtr' vector and
* starts to free the Tcl_Obj pointers contained in the old vector. This
* method should be called from inside of a TclEvent.
*/
static void freeTclObjs () {
Vector newFreeTclObjPtrs = new Vector();
Vector oldFreeTclObjPtrs;
int i;
// we want to quickly grab the content of the existing
// 'freeTclObjPtrs' so that we don't lock the GC thread
synchronized (freeTclObjPtrsLock) {
oldFreeTclObjPtrs = freeTclObjPtrs;
freeTclObjPtrs = newFreeTclObjPtrs;
}
// now we can safely walk through the vector without any
// synchronization problems.
for (i = 0 ; i < oldFreeTclObjPtrs.size() ; i++) {
decrRefCount(((Long) oldFreeTclObjPtrs.elementAt(i)).longValue());
}
}
} // end of CObject
Any comments?
-- Jiang Wu
[EMAIL PROTECTED]
----------------------------------------------------------------
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/[email protected]