Review request for MACOSX_PORT-176: AWT Splashscreen support

Anthony Petrov anthony.petrov at oracle.com
Mon Dec 12 07:19:53 PST 2011


Hi Eric and Mike,

Thanks for reviewing the fix. I've incorporated suggested changes into 
the latest version of the fix at:

http://cr.openjdk.java.net/~anthony/x-3-splashAndOSXGUILib.2/

Some comments follow inline...


On 12/10/11 01:36, Mike Swingler wrote:
>> 3. On the Mac the SplashScreen is initialized only after the JVM has been started and the main application class has been identified, but, obviously, before calling user's main() method. This is because we need the main class name to set the app's name in the dock, as well as we need to access a couple of Java system properties when an NSApplicationAWT instance is created. java.c and java_md.c contain the corresponding changes.
>
> I'm guessing that it will be logical prerequisite for the app name and icon properties to always be set on JVM instantiation, and not by any user code (which using the splash screen).

Well, as long as the app is a GUI app, and only if it uses the splash 
screen. Otherwise the dock icon should only appear if the app 
initializes AWT later when it's already started running. And this is 
exactly how it works now.


> Two major important points:
>
> Structurally, I think the ownership lifecycle of the QueueingApplicationDelegate is somewhat confused. I think it's really bad for to release the qad from the dealloc of the NSApplicationAWT instance. Perhaps you could add a class method to QueueingApplicationDelegate to manage it's singleton existence, and clear it when it's no longer required. Unless the qad is actually an instance variable of the NSApplicationAWT instance, it's really not proper to release it from (what could potentially be multiple instances of) the -dealloc method.

I've implemented +sharedDelegate in QAD. Note that the instance never 
gets released but I don't think this is a big problem because 1) no 
splash screen - no qad is allocated in the first place; 2) the queue 
gets emptied upon processing the events, the rest of the object (two 
booleans, one pointer, and the queue itself) shouldn't occupy too much 
RAM. So I guess we can live with this. We could add a static "release" 
method, however, I don't like the idea since the pointer returned by 
+sharedDelegate could have been stored elsewhere. We could, of course, 
rely on users of the method to properly pair the -retain/-release calls, 
but do we actually need it?


> Also, the QueuingApplicationDelegate should hold onto it's own NSMutableArray and real delegate as ivars, not global statics.

I agree, and I made the queue an instance variable. However, as soon as 
I'm trying to access an ivar from a block, I get crashed. So I left the 
realDelegate static.


> Two minor nits:
>
> I'm generally leery of any code that blocks itself against the main thread (using [JNFRunLoop performOnMainThreadWaiting:YES …), but in the case of the functions that pass the splash pointer, this sadly seem necessary, because the block can't retain that struct like it can for ObjC types. Any chance that the splash struct could be promoted to (or memory managed by) an ObjC object?

We actually have a retention mechanism for the structure in term of a 
custom lock that the splash screen code uses. Note that most platform 
methods that involve blocks are actually called from shared splash 
screen methods, and these shared methods make sure the structure is 
locked while platform methods are running. If we were to use [... 
perform:NO], then we'd have to setup a monitor on the lock, and catch 
the moment the block has finished executing and only then proceed with 
the rest of the platform and/or shared method. I think this would 
complicate the code very significantly. Besides, in most cases the 
blocks are very simple and only invoke Cocoa methods that just have to 
be called on the AppKit thread. So using [:YES] comes very handy and 
reasonable here.

I don't think we want to turn the Splash structure into an ObjC object 
simply because it might require too many changes for no apparent 
benefits - at least not for any of the other platforms. And given that 
the architecture of the splash screen code already involves a custom 
lock, this seems to be of little usefulness.


> Just as a basic ObjC style thing: you don't have to cast to an object type to call a selector as long as the type at runtime is correct. So this:
>
>     BOOL onMainThread = [(NSNumber*)[args objectAtIndex:0] boolValue];
>     BOOL swtMode = [(NSNumber*)[args objectAtIndex:1] boolValue];
>     BOOL headless = [(NSNumber*)[args objectAtIndex:2] boolValue];
>     BOOL swtModeForWebStart = [(NSNumber*)[args objectAtIndex:3] boolValue];
>     BOOL verbose = [(NSNumber*)[args objectAtIndex:4] boolValue];
>
> Could be simply this:
>
>     BOOL onMainThread = [[args objectAtIndex:0] boolValue];
>     BOOL swtMode = [[args objectAtIndex:1] boolValue];
>     BOOL headless = [[args objectAtIndex:2] boolValue];
>     BOOL swtModeForWebStart = [[args objectAtIndex:3] boolValue];
>     BOOL verbose = [[args objectAtIndex:4] boolValue];

I thought a compiler might issue warnings on this, but it doesn't. Cool! 
I've removed the type casts.

--
best regards,
Anthony


More information about the macosx-port-dev mailing list