Mercurial > hg > openjdk > icedtea > jdk7 > jdk
changeset 5424:b521e3a5b843
7124239: [macosx] sun.awt.SunToolkit.InfiniteLoop exception in realSync called from SwingTestHelper
Reviewed-by: anthony, art
author | leonidr |
---|---|
date | Fri, 22 Jun 2012 14:06:40 +0400 |
parents | d68e2a1744bd |
children | 8f37aad76b5b |
files | src/macosx/native/sun/awt/LWCToolkit.m src/macosx/native/sun/osxapp/NSApplicationAWT.h src/macosx/native/sun/osxapp/NSApplicationAWT.m |
diffstat | 3 files changed, 61 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/src/macosx/native/sun/awt/LWCToolkit.m Fri Jun 22 10:20:20 2012 +0100 +++ b/src/macosx/native/sun/awt/LWCToolkit.m Fri Jun 22 14:06:40 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; }
--- a/src/macosx/native/sun/osxapp/NSApplicationAWT.h Fri Jun 22 10:20:20 2012 +0100 +++ b/src/macosx/native/sun/osxapp/NSApplicationAWT.h Fri Jun 22 14:06:40 2012 +0400 @@ -30,11 +30,15 @@ NSString *fApplicationName; BOOL fUseDefaultIcon; NSWindow *eventTransparentWindow; + NSTimeInterval dummyEventTimestamp; + NSConditionLock* seenDummyEventLock; } - (void) finishLaunching; - (void) registerWithProcessManager; - (void) setDockIconWithEnv:(JNIEnv *)env; +- (void) postDummyEvent; +- (void) waitForDummyEvent; + (void) runAWTLoopWithApp:(NSApplication*)app;
--- a/src/macosx/native/sun/osxapp/NSApplicationAWT.m Fri Jun 22 10:20:20 2012 +0100 +++ b/src/macosx/native/sun/osxapp/NSApplicationAWT.m Fri Jun 22 14:06:40 2012 +0400 @@ -32,7 +32,6 @@ #import "ThreadUtilities.h" #import "QueuingApplicationDelegate.h" - static BOOL sUsingDefaultNIB = YES; static NSString *SHARED_FRAMEWORK_BUNDLE = @"/System/Library/Frameworks/JavaVM.framework"; static id <NSApplicationDelegate> applicationDelegate = nil; @@ -53,6 +52,8 @@ AWT_ASSERT_APPKIT_THREAD; fApplicationName = nil; fUseDefaultIcon = NO; + 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. @@ -163,6 +164,7 @@ char mainClassEnvVar[80]; snprintf(mainClassEnvVar, sizeof(mainClassEnvVar), "JAVA_MAIN_CLASS_%d", getpid()); char *mainClass = getenv(mainClassEnvVar); + if (mainClass != NULL) { fApplicationName = [NSString stringWithUTF8String:mainClass]; unsetenv(mainClassEnvVar); @@ -333,6 +335,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