Wow, that's a good analysis of the problem, Hendrik. Thank you.

Would you like to investigate this a bit deeper and come up with a fix for JDK? We would gladly accept a contribution from you. You can find more information on how to get started here: http://openjdk.java.net/contribute/ Also, the patch would need to be reviewed on the awt-dev@ mailing list.

Otherwise, I could only add those comments to the bug report and move it to the JDK project in JIRA so that it becomes visible, but I'm afraid we won't be able to do much on this issue any time soon because we don't have a test app that we could use to reproduce the crash and then confirm whether we've fixed anything or not.

--
best regards,
Anthony

On 8/29/2014 4:45 PM, Hendrik Schreiber wrote:
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

Reply via email to