On Sun, 6 Aug 2000, Jiang Wu wrote:
> This patch should be applied to the
> "ajuba-tclblend-contract-2000-08-01-branch".
>
> The patch includes the following:
>
> - fix bugs in tcl.lang.Notifier
I want to check this all in a bit at a time.
You mention the original bug report:
http://www-cs-students.stanford.edu/~jwu/blendchanges.txt
The bug report is at:
http://dev.scriptics.com/ticket/issue-view.tcl?msg_id=4352
Here is the description from your bug report:
3. In the Java class Notifier, a synchronization deadlock
can happen between "serviceEvent()" and "queueEvent()".
If the main thread for the interpreter is executing a
"vwait" inside a "serviceEvent()", it will block any other
thread from calling "queueEvent()" because the two methods
are synchronized on the Notifier instance object.
The "vwait" command will cause the main
thread to wait inside TclBlend native code. As a result, it does not
relinquish the lock on the Notifier instance object. The fix is to
remove the use of the "synchronized" keyword. Instead, use a private
local mutex object to protect the access to the event list inside
the Nofier object. When the code synchronizes on the local mutex
object, never calls another other methods that may block or
uses other mutex. This prevents deadlock.
I need to create a test case for this Notifier
problem before adding the patch, that way I can
be sure that the patch worked and that it will
stay working in the future.
So it seems like I need to create another
thread that tries to queue up event while
the primary interp thread is stuck inside
a vwait. I tried that, but I was not able
to reproduce a problem with deadlocking
in the queueEvent() method.
Here is the example I tried:
import tcl.lang.*;
public class AppendEventQueueThread extends Thread {
private Interp interpInOtherThread;
public int numQueued = 0;
public int numProcessed = 0;
public boolean killed = false;
private final boolean debug = true;
public AppendEventQueueThread(Interp i) {
interpInOtherThread = i;
}
public void run() {
if (debug) {
System.out.println("running AppendEventQueueThread");
}
while (! killed) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
TclEvent event = new TclEvent() {
public int processEvent (int flags) {
numProcessed++;
return 1;
}
};
// Add the event to the thread safe event queue
interpInOtherThread.getNotifier().queueEvent(event, TCL.QUEUE_TAIL);
numQueued++;
}
if (debug) {
System.out.println("done running AppendEventQueueThread");
}
}
}
# The Tcl code to set this up.
package require java
set AQT [java::new AppendEventQueueThread [java::getinterp]]
$AQT start
set orig_numQueued [java::field $AQT numQueued]
after 10000 "set wait 1"
vwait wait
set numQueued [java::field $AQT numQueued]
set numProcessed [java::field $AQT numProcessed]
# Kill this second thread.
java::field $AQT killed 1
When I ran this example, it did not deadlock in
the Notifier.queueEvent() method. Here is the
output I got:
% set orig_numQueued
0
% set numQueued
9
% set numProcessed
9
This shows that the other thread continued to
run when the main thread was inside a vwait.
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