# HG changeset patch # User serb # Date 1438872932 -10800 # Node ID 269494f7adecf3045b2f5b9550b8a0903b113910 # Parent 193f19028af5875bde4ac9e1ddd0e3e05237963c 7124271: [macosx] RealSync test failure Reviewed-by: alexsch, azvegint diff -r 193f19028af5 -r 269494f7adec jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.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) diff -r 193f19028af5 -r 269494f7adec jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.h --- 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; diff -r 193f19028af5 -r 269494f7adec jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m --- 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;