I wish we could have a coordinated session for discussing topics like
this. Mailing list is not good enough for the sort of collaboration
I'd like to have in my opinion.
jEdit uses several threads to allow concurrency of operations, for
example, buffers are normally loaded in the background. For this
concurrency, jEdit has a class named WorkThreadPool that is used to
queue operations for execution, both in the AWT thread and in other
There are several problems with this class:
1. The method "waitForRequests" invokes "doAwtRequests" without
acquiring the required lock on the request pool.
2. The inner class "RunRequestsInAWTThread" only runs the AWT
operations if there are no pending non-AWT operations, otherwise it
does nothing, and if no further AWT requests are queued, those which
it was called to execute will never be executed. (They will only be
executed the next time an AWT request gets queued.)
These are 2 problems I can see immediately, there may be more. The
consequences of these bugs cannot be easily derived, but there are a
few difficult and high-priority bugs that might result from these
problems, such as the text area painting corruption when saving (which
is easily reproducible), and the deadlock on startup (which I
personally haven't experienced in a while).
This code in jEdit was added long ago, probably before Java included
its own thread pools in the APIs. I think this class should be
replaced with the standard threading support provided by Java, and all
uses of it should be updated. Any thoughts? I can make this change
myself, and submit patches for review.
I noticed that this class in jEdit is commonly used as the following:
Some request is queued to execute in a non-AWT thread (e.g. SideKick's
parsing of the buffer), then another request, that logically depends
on the completion of the first request, is queued to execute in the
AWT thread (such as the update of the SideKick tree with the results
of the parsing). The AWT request is queued independently of the first
request, but the WorkThreadPool ensures (or at least, it is supposed
to ensure) that the queued AWT requests do not execute before all
queued non-AWT requests have executed. This is, in my opinion, a
twisted approach, which also gives up some concurrency. I think the
right way to do it is to queue the AWT request for execution in the
AWT thread at the end of the non-AWT request. So the code for the
non-AWT request would queue the AWT one before returning. This way,
the AWT request does not have to wait for other, possibly unrelated,
non-AWT requests to complete.