On Aug 28, 2014, at 20:16, Anthony Petrov <anthony.pet...@oracle.com> wrote:
> JI-9014527 was closed as Incomplete "Not enough information.", supposedly > because there's not a reproducible test case and instructions to reproduce > the issue. That is correct. I erroneously assumed that people reviewing bug reports would be interested in crashes, and their crashlogs, even if they do not contain step-by-step instructions on how to reproduce the issue. > If you come up with a simple test that crashes easily, we can re-open that > bug. I wish I could. > BTW, from the full stack trace in the bug report I can see you're running > some accessibility software on your system because the crash happens during > an a11y callback. This may be a contributing factor to the crash. You will > need to test with and without a11y on, and also perhaps try another assistive > technology (e.g. the built-in VoiceOver vs. a third-party software) to see if > this changes anything. Digging into the source code it becomes clear that Java_sun_lwawt_macosx_LWCToolkit_stopAWTRunLoop is only called from - sun.lwawt.macosx.CToolkitThreadBlockedHandler and - sun.lwawt.macosx.LWCToolkit The call from LWCToolkit is coded defensively, i.e. it has a 0-check: if (mediator != 0) { stopAWTRunLoop(mediator); } Therefore it cannot lead to the failure described in http://www.beatunes.com/download/stopAWTRunLoop.crash The call from CToolkitThreadBlockedHandler is NOT coded defensively. To the contrary, it relies on the implicit contract, that the exit() method is called at most once after the enter() method is called: public void exit() { if (!isOwned()) { throw new IllegalMonitorStateException(); } LWCToolkit.stopAWTRunLoop(awtRunLoopMediator); awtRunLoopMediator = 0; } It might be a good idea to simply guard against other classes using enter()/exit() in unintended ways by rewriting it defensively like this: public void enter() { if (!isOwned()) { throw new IllegalMonitorStateException(); } if (awtRunLoopMediator != 0) { throw new IllegalStateException("Call exit() first."); } awtRunLoopMediator = LWCToolkit.createAWTRunLoopMediator(); unlock(); LWCToolkit.doAWTRunLoop(awtRunLoopMediator, processEvents); lock(); } public void exit() { if (!isOwned()) { throw new IllegalMonitorStateException(); } if (awtRunLoopMediator != 0) { LWCToolkit.stopAWTRunLoop(awtRunLoopMediator); awtRunLoopMediator = 0; } } That said, enter() and exit() are only called from one place, sun.awt.datatransfer.DataTransferer#convertData(...). My guess is, that for some reason getToolkitThreadBlockedHandler().exit(); is either called multiple times or LWCToolkit.createAWTRunLoopMediator() in CToolkitThreadBlockedHandler#enter() returns 0 for whatever reason. Frankly, I don't quite understand how it can happen that the dataConverter Runnable in DataTransferer#convertData(...) is executed multiple times, but clearly it is a problem, as the code tries to guard against it. It does not do so in a threadsafe way though. Anyhow. I would appreciate it, if you considered reviewing both my suggestion for improving sun.lwawt.macosx.CToolkitThreadBlockedHandler and perhaps the code in sun.awt.datatransfer.DataTransferer to improve the stability of the Java VM on OS X. Thank you. -hendrik