Q regarding threading issues for SWT mode

Scott Kovatch scott.kovatch at oracle.com
Tue Dec 13 10:52:08 PST 2011


Anthony,

I wrote a lot of that code originally, and amazingly enough, I still recall what it needs to accomplish. My answers are inline.

On Dec 13, 2011, at 5:28 AM, Anthony Petrov wrote:

> Hi Mike, Steve,
> 
> There's a couple of issues ([1] and [2]) that arise when running Java in the SWT-compatible mode (i.e. with the -XstartOnFirstThread specified). I've got a couple of questions for you guys.
> 
> 1. I would second to Mike's comment in [2] regarding mandating that the SWT must already be running the event loop before trying to access AWT. What bothers me though, is that these same applications work fine with Apple JDK (according to user comments), but fail only when running with OpenJDK. Is that only because of the AWT_ASSERT_NOT_APPKIT_THREAD assertion at line 267 in awt.m at:
> 
> http://hg.openjdk.java.net/macosx-port/macosx-port/jdk/file/13d69fd25daa/src/macosx/native/sun/awt/awt.m
> 
> which actually seems to be completely unnecessary there? Or might there be any other reason?

I agree with you -- there's no need for that assertion. The notification NSApplicationDidFinishLaunchingNotification will always fire on the main thread, and registering that notification has nothing to do with what thread you are on. 

Removing this line will correctly fix both of the bugs you mentioned.

While it is true that AWT event handling and other access should only happen on the EDT thread we can't realistically enforce that behavior at this point as there's too much code that relies on AWT's free-threadedness. This also extends to AWT startup -- we can't realistically force code to start AWT on any particular thread.

> Or will we actually start a new Cocoa loop for the AWT? There's a comment at line 335 that says SWT doesn't call NSApplicationLoad(). The spec for NSApplicationLoad() states this function initializes an instance of NSApplication. So do I understand correctly that SWT itself does NOT actually create its own NSApp instance?

Note that NSApplicationLoad() only creates and initializes an NSApplication instance. It does NOT start up an event loop, which is important.

>  Is SWT a Carbon-only library?

There was a Carbon version of the SWT, but a Cocoa version was added in 2008 for Eclipse 3.5. Beginning with Eclipse 3.8 (I think), the Carbon version of the SWT is no longer being built or distributed.

NSApplicationLoad will create an instance of NSApplication that returns isRunning on the assumption that a Carbon application is running an event loop. If the Carbon SWT is running, that is the case. If not, it will be, so this is still what we want. We need to keep line 354 from executing, or else the AWT will start up and never get back to the SWT.

For the Cocoa SWT, it's trickier. If it has already started, NSApplicationLoad has no effect because there is already an NSApplication in the running state. If it has NOT already started, we could just create an NSApplication here, but it won't return YES when we call isRunning. So, NSApplicationLoad turns out to be the right thing for either the Carbon or Cocoa SWT.

Calling NSApplicationLoad has the good side effect of preventing NSApplicationAWT's constructor from running when we call [NSApplicationAWT sharedApplication] at line 343. We want that because the SWT will also create and manage the menu bar.

If the Cocoa SWT is already running, NSApplicationLoad has no effect, which is what we want. It's only called when 'start on main thread' is used and the AWT is started before the SWT.

So, back to your original question #2 and its rewording:

> 2. If we've started the VM on the main thread, and let's suppose SWT has already been initialized. Do I understand correctly that at line 350 of the aforementioned file we'll see that the app is already running?

> To rephrase my question: if Cocoa code (AWT) is embedded within a Carbon app (SWT), would [NSApp isRunning] return YES or NO after the Carbon app has already been initialized and is running? My guess is that it would still return YES even though there was not an explicit initialization of the Cocoa event loop, but I'd like to double check this with those who have expertise in Cocoa/Carbon/SWT.

This is correct. If the SWT is running its event loop already, there is an NSApplication instance and it will return isRunning == YES at line 350.

Hope that helps. It was long-winded, but this is odd code, particularly at first glance.

-- Scott K.



More information about the macosx-port-dev mailing list