# HG changeset patch # User leonidr # Date 1348485917 -14400 # Node ID e62879b84a14ee6595f4a71b7f61d4a51e5d7fc0 # Parent 3e72145fd93ae37e1ee566ecc3ae3cdc7a090c36 7124239: [macosx] sun.awt.SunToolkit.InfiniteLoop exception in realSync called from SwingTestHelper Reviewed-by: anthony diff -r 3e72145fd93a -r e62879b84a14 jdk/src/macosx/native/sun/awt/LWCToolkit.m --- a/jdk/src/macosx/native/sun/awt/LWCToolkit.m Fri Sep 21 13:48:06 2012 +0400 +++ b/jdk/src/macosx/native/sun/awt/LWCToolkit.m Mon Sep 24 15:25:17 2012 +0400 @@ -33,6 +33,7 @@ #import "ThreadUtilities.h" #import "AWT_debug.h" #import "CSystemColors.h" +#import "NSApplicationAWT.h" #import "sun_lwawt_macosx_LWCToolkit.h" @@ -47,7 +48,7 @@ return eventCount; } -+ (void) eventCountPlusPlus{ ++ (void) eventCountPlusPlus{ eventCount++; } @@ -79,7 +80,6 @@ @end - /* * Class: sun_lwawt_macosx_LWCToolkit * Method: nativeSyncQueue @@ -90,12 +90,22 @@ { int currentEventNum = [AWTToolkit getEventCount]; - [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){}]; - + NSApplication* sharedApp = [NSApplication sharedApplication]; + if ([sharedApp isKindOfClass:[NSApplicationAWT class]]) { + NSApplicationAWT* theApp = (NSApplicationAWT*)sharedApp; + [theApp postDummyEvent]; + [theApp waitForDummyEvent]; + } else { + // could happen if we are embedded inside SWT application, + // 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; } diff -r 3e72145fd93a -r e62879b84a14 jdk/src/macosx/native/sun/osxapp/NSApplicationAWT.h --- a/jdk/src/macosx/native/sun/osxapp/NSApplicationAWT.h Fri Sep 21 13:48:06 2012 +0400 +++ b/jdk/src/macosx/native/sun/osxapp/NSApplicationAWT.h Mon Sep 24 15:25:17 2012 +0400 @@ -29,11 +29,15 @@ @interface NSApplicationAWT : NSApplication { NSString *fApplicationName; NSWindow *eventTransparentWindow; + NSTimeInterval dummyEventTimestamp; + NSConditionLock* seenDummyEventLock; } - (void) finishLaunching; - (void) registerWithProcessManager; - (void) setDockIconWithEnv:(JNIEnv *)env; +- (void) postDummyEvent; +- (void) waitForDummyEvent; + (void) runAWTLoopWithApp:(NSApplication*)app; diff -r 3e72145fd93a -r e62879b84a14 jdk/src/macosx/native/sun/osxapp/NSApplicationAWT.m --- a/jdk/src/macosx/native/sun/osxapp/NSApplicationAWT.m Fri Sep 21 13:48:06 2012 +0400 +++ b/jdk/src/macosx/native/sun/osxapp/NSApplicationAWT.m Mon Sep 24 15:25:17 2012 +0400 @@ -52,6 +52,9 @@ AWT_ASSERT_APPKIT_THREAD; fApplicationName = nil; + dummyEventTimestamp = 0.0; + seenDummyEventLock = nil; + // NSApplication will call _RegisterApplication with the application's bundle, but there may not be one. // So, we need to call it ourselves to ensure the app is set up properly. @@ -328,6 +331,45 @@ return event; } +// NSTimeInterval has microseconds precision +#define TS_EQUAL(ts1, ts2) (fabs((ts1) - (ts2)) < 1e-6) + +- (void)sendEvent:(NSEvent *)event +{ + if ([event type] == NSApplicationDefined && TS_EQUAL([event timestamp], dummyEventTimestamp)) { + [seenDummyEventLock lockWhenCondition:NO]; + [seenDummyEventLock unlockWithCondition:YES]; + } else { + [super sendEvent:event]; + } +} + +- (void)postDummyEvent { + seenDummyEventLock = [[NSConditionLock alloc] initWithCondition:NO]; + dummyEventTimestamp = [NSProcessInfo processInfo].systemUptime; + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSEvent* event = [NSEvent otherEventWithType: NSApplicationDefined + location: NSMakePoint(0,0) + modifierFlags: 0 + timestamp: dummyEventTimestamp + windowNumber: 0 + context: nil + subtype: 0 + data1: 0 + data2: 0]; + [NSApp postEvent: event atStart: NO]; + [pool drain]; +} + +- (void)waitForDummyEvent { + [seenDummyEventLock lockWhenCondition:YES]; + [seenDummyEventLock unlock]; + [seenDummyEventLock release]; + + seenDummyEventLock = nil; +} + @end