<AWT Dev> [8] Review request for 8005465: [macosx] Evaluate if checking for the -XstartOnFirstThread is still needed in awt.m

Anthony Petrov anthony.petrov at oracle.com
Fri Jan 11 07:56:33 PST 2013


On 1/11/2013 19:30, steve.x.northover at oracle.com wrote:
> Thanks for the info.  I don't have a solution other than knowing that 
> SWT is there but let's talk about it.
> 
> I understand that when -XstartOnFirstThread is specified, AWT gets 
> started on the main thread (gui thread) and if AWT starts it's own event 
> loop (either running it right away or performing it later on the main 
> thread (I understand we are already on the main thread but we could post 
> cocoa work for later)), then this will block SWT's event loop when it 
> executes the work for AWT.  Is that correct?

Not exactly. Where AWT is started is determined by user code. The 
-XstartOnFirstThread just allows the user's main() to be run on the main 
thread. User's code can get to the main thread by other means (like the 
AWT itself does when running standalone, for example, using the 
performSelector: - see AWTStarter -start in awt.m).

With my fix AWT is able to detect (regardless on what thread it's been 
started) if someone else is already running an event loop by calling 
[NSApp isRunning] (see AWTStarter -starter - (!) it's not the -start).

In 99.999% of cases SWT (or e.g. FX) is already running an event loop, 
and therefore, AWT detects that and won't start its own loop (regardless 
of the thread where the AWT has been started off.)

We can only run into a problem if a user runs:

$ java -XstartOnFirstThread app

where the app is doing something like this:

main()
{
    awt.Toolkit.getDefaultToolkit();

    // and now let's proceed with usual SWT code
    // ...
}

In this case the first line will cause the AWT to load, we detect that 
no-one is running an event loop yet and start our own one, thus 
effectively blocking the main() at this point.

If AWT knew SWT was going to run, we could probably not start our own 
event loop. Do we want to support this use-case?

I'm asking, because otherwise, i.e. if SWT is always initialized first, 
then no matter where you start AWT (main thread or not), it will run 
just fine re-using the existing SWT's event loop.

--
best regards,
Anthony


> If we knew that SWT was there or was not there, would this make any 
> difference?  ie. what bug would we be fixing?  If someone used 
> -XstartOnFirstThread and then did not run an event loop, AWT/Swing would 
> work providing that the Java code that was executed returned from Java 
> main()?  Is that it?
> 
> I wonder if, when AWT is initialized on the main thread, it posted cocoa 
> event loop work for itself.  If the event loop work is executed in Java 
> main(), then someone (SWT) is running an event loop from there and it is 
> not necessary to run the AWT event loop.  If Java main() has exited, 
> then AWT can run the event loop.
> 
> Steve
> 
> On 11/01/2013 8:47 AM, Anthony Petrov wrote:
>> Steve,
>>
>> To answer your question: no, we're not removing -XstartOnFirstThread 
>> from the JDK. We just no longer check this flag when initializing AWT 
>> because it can be initialized either way. Note, however, that AWT 
>> expects that the SWT is already running its event loop when AWT is 
>> starting up on the main thread. If it's not true, then AWT will start 
>> its own loop and therefore block the main thread for the code that 
>> caused the AWT to start up on the main thread in the first place. I 
>> think this situation is unlikely to occur though, but there's simply 
>> not a better solution because AWT requires a native event loop, and it 
>> can't be sure if someone else is going to start it later on.
>>
>> -- 
>> best regards,
>> Anthony
>>
>> On 1/11/2013 17:37, Petr Pchelko wrote:
>>> Hello, Steve.
>>>
>>> You've asked for a code sample. Sorry for the delay, here is it.
>>> If you close SWT window first - AWT hangs.
>>> With best regards. Petr.
>>>
>>>
>>> ------------------------------------------------------------------------
>>>
>>>
>>>
>>> On Jan 10, 2013, at 9:06 PM, steve.x.northover at oracle.com wrote:
>>>
>>>> Hi all,
>>>>
>>>> I'm a little out of the loop with respect to what is going on here.  
>>>> Please bear with me.
>>>>
>>>> First off, we are not removing -XstartOnFirstThread from the JDK, 
>>>> correct?  SWT does not expect other event loops or toolkits to be 
>>>> running.  Like a native application, it expects to be able to run an 
>>>> event loop in main().  The -XstartOnFirstThread forces Java main() 
>>>> to be the same thread C main(), which is the Cocoa GUI thread.
>>>>
>>>> Can you attach the example code that is failing so I can see what we 
>>>> are trying to do?
>>>>
>>>> Steve
>>>>
>>>> On 10/01/2013 11:23 AM, Petr Pchelko wrote:
>>>>> Hello again.
>>>>>
>>>>> Sergey wrote:
>>>>>>> As far as I understand from the discussion SWT doesn't survive 
>>>>>>> situation, when we open 2 window(SWT and AWT) and close SWT 
>>>>>>> window first. Since in this case SWT stops appkit run loop. This 
>>>>>>> fix works in this case and this means that we should apply the 
>>>>>>> same patch to SWT.
>>>>>>> Petr, can you clarify this? Thanks
>>>>> I have applied the patch and tried a little example with SWT Window 
>>>>> and AWT Frame. The app still hangs in case the SWT Frame is closed 
>>>>> first. The problem is that in SWT the common pattern is to put such 
>>>>> code to the end of main:
>>>>>
>>>>>  while (!shell.isDisposed()) {
>>>>>             if (!display.readAndDispatch()) display.sleep();
>>>>>  }
>>>>>  display.dispose();
>>>>> //end of main function
>>>>>
>>>>> (It is so common that it is in the first helloworld example in the 
>>>>> SWT documentation)
>>>>>
>>>>> So, SWT does not care about the native events, it shuts down as 
>>>>> soon as Shell gets disposed. The main thread finishes and AWT hangs.
>>>>>
>>>>> I don't think we could fix the issue in AWT, but there is a simple 
>>>>> workaround to add a dispose listener to the shell which would spin 
>>>>> the runloop until AWTAutoShutdown.isReadyToShutdown, so it could be 
>>>>> fixed in SWT.
>>>>> However, the case when AWT and SWT windows are opened 
>>>>> simultaneously is so likely to produce deadlocks that I am not sure 
>>>>> we want to support this case at all. JDK6 does not.
>>>>>
>>>>> As for the embedded case, the issue with shutdown is fixed on the 
>>>>> SWT side, however, making the AWTAutoShutdown method public would 
>>>>> allow to make the solution better.
>>>>>
>>>>> With best regards. Petr.
>>>>>
>>>>> This fix actually does not help in the case when SWT
>>>>> On Jan 10, 2013, at 6:24 PM, Petr Pchelko wrote:
>>>>>
>>>>>> Yes. SWT did not survive in such a situation. A will try to apply 
>>>>>> the fix and test if it helps with the SWT.
>>>>>>
>>>>>> With best regards. Petr.
>>>>>>
>>>>>> On Jan 10, 2013, at 6:13 PM, Sergey Bylokhov wrote:
>>>>>>
>>>>>>> 10.01.2013 17:55, Anthony Petrov wrote:
>>>>>>>> Thanks Petr. I think we don't want to do the same in FX because 
>>>>>>>> we don't even want to call any AWT APIs from there in the first 
>>>>>>>> place. Instead, my current solution offers a way to terminate 
>>>>>>>> both toolkits graciously.
>>>>>>> As far as I understand from the discussion SWT doesn't survive 
>>>>>>> situation, when we open 2 window(SWT and AWT) and close SWT 
>>>>>>> window first. Since in this case SWT stops appkit run loop. This 
>>>>>>> fix works in this case and this means that we should apply the 
>>>>>>> same patch to SWT.
>>>>>>> Petr, can you clarify this? Thanks
>>>>>>>> Sergey, does this resolve your concern?
>>>>>>>>
>>>>>>>> -- 
>>>>>>>> best regards,
>>>>>>>> Anthony
>>>>>>>>
>>>>>>>> On 12/28/12 23:06, Petr Pchelko wrote:
>>>>>>>>> Hello.
>>>>>>>>>
>>>>>>>>> As I understood while implementing the EmbeddedFrame, when we 
>>>>>>>>> embed AWT into SWT, SWT did not care if AWT is OK to terminate, 
>>>>>>>>> SWT just called dispose() for a frame and terminated without 
>>>>>>>>> looking at AWT. This resulted in issues when AWT was still 
>>>>>>>>> terminating but the main SWT thread was already finished. When 
>>>>>>>>> AWT was calling something to synchronously perform selectors on 
>>>>>>>>> the main thread deadlocks occurred. So we had to add a dispose 
>>>>>>>>> listener to the SWT container, which spinned the main runloop 
>>>>>>>>> until AWT frame finished disposing.
>>>>>>>>>
>>>>>>>>> However, I may have misunderstood something.
>>>>>>>>>
>>>>>>>>> With best regards, Petr.
>>>>>>>>>
>>>>>>>>> 28.12.2012, в 20:58, Anthony 
>>>>>>>>> Petrov<anthony.petrov at oracle.com>   написал(а):
>>>>>>>>>
>>>>>>>>>> On 12/28/2012 20:36, Sergey Bylokhov wrote:
>>>>>>>>>>>> http://cr.openjdk.java.net/~anthony/8-52-startOnFirstThreadCheck-8005465.0/ 
>>>>>>>>>>>>
>>>>>>>>>>>> 2. Introducing an AWTKeepAlive thread activated in the 
>>>>>>>>>>>> embedded mode only. This thread will send an event to the 
>>>>>>>>>>>> native event queue every 500ms as long as there are active 
>>>>>>>>>>>> AWT objects present. This activity will notify the embedder 
>>>>>>>>>>>> toolkit that the Java application as a whole is still alive 
>>>>>>>>>>>> and needs not exit yet.
>>>>>>>>>>> Why it wasn't necessary for awt-swt bridge?
>>>>>>>>>> I don't know. Perhaps we should ask someone who's familiar 
>>>>>>>>>> with SWT? Steve? How does SWT determine that AWT is dead and 
>>>>>>>>>> therefore it's OK to terminate the native event loop and exit 
>>>>>>>>>> on the Mac?
>>>>>>>>>>
>>>>>>>>>> -- 
>>>>>>>>>> best regards,
>>>>>>>>>> Anthony
>>>>>>> -- 
>>>>>>> Best regards, Sergey.
>>>>>>>
>>>



More information about the awt-dev mailing list