I took another look at the JLS and it does seem to be
perfectly legal to keep a ref to an object after the
finalize() method has been run. Because of this, it
is possible to turn the CObject into a TclEvent
and enqueue it directly. The only catch is that
CObject already extends InternalRep, and MI
is not allowed in Java.
Of course, InternalRep is just an abstract class,
so I don't see any real reason why we should not
be able to just turn it into an interface. With
that change, CObject can be made to extend
TclEvent, like so:
Don't try to apply this patch, it is just a mock
up. To really get this working requires patching
about 20 files, so this is just to give you
the flavor idea of how it works. I ran this
through the test suite, and it seems to be
working just fine.
--- CObject.java 1998/10/14 21:09:10 1.1.1.1
+++ CObject.java 2000/10/23 05:37:24
-class CObject extends InternalRep {
+class CObject extends TclEvent implements InternalRep {
@@ -76,6 +71,12 @@
{
this.objPtr = objPtr;
incrRefCount(objPtr);
+
+ // Use the notifier member from the TclEvent class
+ // to hold a ref to the Notifier this CObject
+ // was created in.
+
+ notifier = Notifier.getNotifierForThread(Thread.currentThread());
}
^L
/*
@@ -217,12 +219,18 @@
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*.
- */
+ // If a CObject is finalized while the reference is still valid,
+ // we need to send the reference back to the thread that created it.
+ // We can then sever the connection to the underlying Tcl_Obj* by
+ // calling decrRefCount() in that thread. Note that we can not wait
+ // for the event to be processed, as that would block the GC thread.
+ // Also note that this is a little tricky because the object has
+ // already been finalized by the time be put it back into the queue.
+ // This is ok because the memory will not be garbage collected until
+ // after the event has been processed and the last reference dropped.
- decrRefCount(objPtr);
+ notifier.queueEvent(this, TCL.QUEUE_TAIL);
}
super.finalize();
}
@@ -230,6 +238,29 @@
+
+public int processEvent(int flags) {
+ return 1;
+}
Any comments on changing InternalRep over to an
interface or this approach to putting a CObject
directly into the event queue?
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/[email protected]