7124271: [macosx] RealSync test failure
authorserb
Thu, 06 Aug 2015 17:55:32 +0300
changeset 32293 269494f7adec
parent 32292 193f19028af5
child 32294 58789f875b54
7124271: [macosx] RealSync test failure Reviewed-by: alexsch, azvegint
jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m
jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.h
jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m	Fri Aug 14 13:59:40 2015 -0500
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m	Thu Aug 06 17:55:32 2015 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -71,7 +71,7 @@
     return eventCount;
 }
 
-+ (void) eventCountPlusPlus{    
++ (void) eventCountPlusPlus{
     eventCount++;
 }
 
@@ -167,7 +167,7 @@
                                                ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
                                                    setBusy(YES);
                                                });
-        
+
         CFRunLoopObserverRef notBusyObserver = CFRunLoopObserverCreateWithHandler(
                                                 NULL,                        // CFAllocator
                                                 kCFRunLoopBeforeWaiting,     // CFOptionFlags
@@ -176,14 +176,14 @@
                                                 ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
                                                     setBusy(NO);
                                                 });
-        
+
         CFRunLoopRef runLoop = [[NSRunLoop currentRunLoop] getCFRunLoop];
         CFRunLoopAddObserver(runLoop, busyObserver, kCFRunLoopDefaultMode);
         CFRunLoopAddObserver(runLoop, notBusyObserver, kCFRunLoopDefaultMode);
-        
+
         CFRelease(busyObserver);
         CFRelease(notBusyObserver);
-        
+
         setBusy(YES);
     }
 
@@ -344,19 +344,19 @@
         // We're either embedded, or showing a splash screen
         if (isEmbedded) {
             AWT_STARTUP_LOG(@"running embedded");
-            
+
             // We don't track if the runloop is busy, so set it free to let AWT finish when it needs
             setBusy(NO);
         } else {
             AWT_STARTUP_LOG(@"running after showing a splash screen");
         }
-        
+
         // Signal so that JNI_OnLoad can proceed.
         if (!wasOnMainThread) [AWTStarter appKitIsRunning:nil];
-        
+
         // Proceed to exit this call as there is no reason to run the NSApplication event loop.
     }
-    
+
     [pool drain];
 }
 
@@ -370,24 +370,34 @@
 JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_LWCToolkit_nativeSyncQueue
 (JNIEnv *env, jobject self, jlong timeout)
 {
-    int currentEventNum = [AWTToolkit getEventCount];
+    long currentEventNum = [AWTToolkit getEventCount];
 
     NSApplication* sharedApp = [NSApplication sharedApplication];
     if ([sharedApp isKindOfClass:[NSApplicationAWT class]]) {
         NSApplicationAWT* theApp = (NSApplicationAWT*)sharedApp;
-        [theApp postDummyEvent];
-        [theApp waitForDummyEvent:timeout];
+        // We use two different API to post events to the application,
+        //  - [NSApplication postEvent]
+        //  - CGEventPost(), see CRobot.m
+        // It was found that if we post an event via CGEventPost in robot and
+        // immediately after this we will post the second event via
+        // [NSApp postEvent] then sometimes the second event will be handled
+        // first. The opposite isn't proved, but we use both here to be safer.
+        [theApp postDummyEvent:false];
+        [theApp waitForDummyEvent:timeout / 2.0];
+        [theApp postDummyEvent:true];
+        [theApp waitForDummyEvent:timeout / 2.0];
+
     } else {
         // could happen if we are embedded inside SWT application,
-        // in this case just spin a single empty block through 
+        // in this case just spin a single empty block through
         // the event loop to give it a chance to process pending events
         [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){}];
     }
-    
+
     if (([AWTToolkit getEventCount] - currentEventNum) != 0) {
         return JNI_TRUE;
     }
-        
+
     return JNI_FALSE;
 }
 
@@ -516,7 +526,7 @@
                                              beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.010]];
         if (processEvents) {
             //We do not spin a runloop here as date is nil, so does not matter which mode to use
-            // Processing all events excluding NSApplicationDefined which need to be processed 
+            // Processing all events excluding NSApplicationDefined which need to be processed
             // on the main loop only (those events are intended for disposing resources)
             NSEvent *event;
             if ((event = [NSApp nextEventMatchingMask:(NSAnyEventMask & ~NSApplicationDefined)
--- a/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.h	Fri Aug 14 13:59:40 2015 -0500
+++ b/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.h	Thu Aug 06 17:55:32 2015 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,9 +36,9 @@
 - (void) finishLaunching;
 - (void) registerWithProcessManager;
 - (void) setDockIconWithEnv:(JNIEnv *)env;
-- (void) postDummyEvent;
+- (void) postDummyEvent:(bool) useCocoa;
 - (void) postRunnableEvent:(void (^)())block;
-- (void) waitForDummyEvent:(long long) timeout;
+- (void) waitForDummyEvent:(double) timeout;
 
 + (void) runAWTLoopWithApp:(NSApplication*)app;
 
--- a/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m	Fri Aug 14 13:59:40 2015 -0500
+++ b/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m	Thu Aug 06 17:55:32 2015 +0300
@@ -349,6 +349,7 @@
             && [event subtype] == NativeSyncQueueEvent) {
         [seenDummyEventLock lockWhenCondition:NO];
         [seenDummyEventLock unlockWithCondition:YES];
+
     } else if ([event type] == NSApplicationDefined && [event subtype] == ExecuteBlockEvent) {
         void (^block)() = (void (^)()) [event data1];
         block();
@@ -387,9 +388,7 @@
     [pool drain];
 }
 
-
-
-- (void)postDummyEvent {
+- (void)postDummyEvent:(bool)useCocoa {
     seenDummyEventLock = [[NSConditionLock alloc] initWithCondition:NO];
     dummyEventTimestamp = [NSProcessInfo processInfo].systemUptime;
 
@@ -403,19 +402,28 @@
                                          subtype: NativeSyncQueueEvent
                                            data1: 0
                                            data2: 0];
-    [NSApp postEvent: event atStart: NO];
+    if (useCocoa) {
+        [NSApp postEvent:event atStart:NO];
+    } else {
+        ProcessSerialNumber psn;
+        GetCurrentProcess(&psn);
+        CGEventPostToPSN(&psn, [event CGEvent]);
+    }
     [pool drain];
 }
 
-- (void)waitForDummyEvent:(long long) timeout {
+- (void)waitForDummyEvent:(double)timeout {
+    bool unlock = true;
     if (timeout >= 0) {
-        double sec = ((double) timeout)/1000;
-        [seenDummyEventLock lockWhenCondition:YES
+        double sec = timeout / 1000;
+        unlock = [seenDummyEventLock lockWhenCondition:YES
                                beforeDate:[NSDate dateWithTimeIntervalSinceNow:sec]];
     } else {
         [seenDummyEventLock lockWhenCondition:YES];
     }
-    [seenDummyEventLock unlock];
+    if (unlock) {
+        [seenDummyEventLock unlock];
+    }
     [seenDummyEventLock release];
 
     seenDummyEventLock = nil;