This is a fix for bug #3134951 - "Open file via hyper search overrides result line". The regression occurred because HyperSearchResult got updated to the new threading API, while EditPane was still using runInAWTThread, so the caret updates got run in the wrong order.
Thank you for the patch. But unfortunately, it seems incomplete.
I tried the patch against jEdit trunk r19187, JDK 6u23, Windows XP. It
worked 4 times for 10 trials.
Sorry but I don't have enough time now to give more analysis. I'll take
a deeper look later.
Did you do anything specific in the failed trials? I'm on a different setup here, but I've done a few hundred trials with different parameters (file size, cpu load, adding explicit delays in the code), and I haven't been able to get it to fail.
In detail, I set -nosettings, and used README.SRC.txt in jEdit source
tree, and did Hypersearch for the word "This" at line 3. After that, I
repeated ...
- Ctrl+Home (bring the cursor to the beginning of the file),
- Ctrl+W (closing the buffer),
- clicking the first occurrence of floating Hypersearch dockable.
In working case, the cursor goes to line 3 and the word "This" is
selected. In failing case, the cursor goes to the beginning of the file.
If you still couldn't see the failing case, please report your
environment.
I'm Mac OSX 10.6.5 running "Java for Mac OS X 10.6, Update 3" (equivalent to JDK 6u22). I applied the patch to trunk r19187, and used the same process you described above. No failures in a few dozen trials. It also seems to work correctly with OpenJDK6.
Also works on Ubuntu 10.04.1 with OpenJDK 6u20, and on Vista with JRE 6u5.
Perhaps the threading policies among OS, or the number of processor core
caused the difference. My processor is Intel Pentium M 2.00GHz (single
core).
I found that replacing the call of EventQueue.invokeLater() to
ThreadUtilities.runInDispatchThread() appears to fix the problem. But
I'm not sure yet about what was the failing scenario and how the
replacement affects it.
What was happening on a single core env.
An activity log with some additional log about GotoDelayed is attached.
Now I got a guess about what was happening:
1. In GotoDelayed constructor, getBuffer() starts loading of buffer in
it. If the loading isn't completed immediately, a post-loading task
is queued into the EDT via VFSManager.runInAWTThread .
2. After that, editPane.setBuffer() is called and loadCaretInfo() is
queued into the EDT via EventQueue.invokeLater() .
3. If the loading is completed here, the post-loading task runs in the
EDT as queued in step 1, and GotoDelayed do the job via
EditBus.send(BufferUpdate.LOADED) .
4. Finally, loadCaretInfo() is called in the EDT as queued in step 2,
and causes the problem.
The replacement from invokeLater() to runInDispatchThread() eliminates
the unnecessary queuing at step 2, and solves the problem.
I have understood why the problem happened only on my single core
environment because the both two "if"s in step 1 and 3 is hardly holds
true on multi core environments as a thread BufferLoadRequest can be
invoked and completed immediately in getBuffer(); it will completes
either immediately or after some time enough to be delayed after the
loadCaretInfo() .
Committed the fix as r19199 with the replacement and some tweaks.
http://jedit.svn.sourceforge.net/jedit/?view=rev&rev=19199
Thank you very much.