8068886: IDEA IntelliJ crashes in objc_msgSend when an accessibility tool is enabled
Reviewed-by: serb, bae
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CFRetainedResource.m Thu Jun 04 15:24:30 2015 +0300
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CFRetainedResource.m Thu Jun 04 16:18:14 2015 +0300
@@ -23,6 +23,7 @@
* questions.
*/
+#import <Cocoa/Cocoa.h>
#import <JavaNativeFoundation/JavaNativeFoundation.h>
#import "sun_lwawt_macosx_CFRetainedResource.h"
@@ -37,7 +38,10 @@
(JNIEnv *env, jclass clazz, jlong ptr, jboolean releaseOnAppKitThread)
{
if (releaseOnAppKitThread) {
- [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
+ // Releasing resources on the main AppKit message loop only
+ // Releasing resources on the nested loops may cause dangling
+ // pointers after the nested loop is exited
+ [NSApp postRunnableEvent:^(){
CFRelease(jlong_to_ptr(ptr));
}];
} else {
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m Thu Jun 04 15:24:30 2015 +0300
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m Thu Jun 04 16:18:14 2015 +0300
@@ -516,8 +516,10 @@
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
+ // on the main loop only (those events are intended for disposing resources)
NSEvent *event;
- if ((event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ if ((event = [NSApp nextEventMatchingMask:(NSAnyEventMask & ~NSApplicationDefined)
untilDate:nil
inMode:NSDefaultRunLoopMode
dequeue:YES]) != nil) {
--- a/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.h Thu Jun 04 15:24:30 2015 +0300
+++ b/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.h Thu Jun 04 16:18:14 2015 +0300
@@ -37,6 +37,7 @@
- (void) registerWithProcessManager;
- (void) setDockIconWithEnv:(JNIEnv *)env;
- (void) postDummyEvent;
+- (void) postRunnableEvent:(void (^)())block;
- (void) waitForDummyEvent;
+ (void) runAWTLoopWithApp:(NSApplication*)app;
--- a/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m Thu Jun 04 15:24:30 2015 +0300
+++ b/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m Thu Jun 04 16:18:14 2015 +0300
@@ -337,9 +337,13 @@
- (void)sendEvent:(NSEvent *)event
{
- if ([event type] == NSApplicationDefined && TS_EQUAL([event timestamp], dummyEventTimestamp)) {
+ if ([event type] == NSApplicationDefined && TS_EQUAL([event timestamp], dummyEventTimestamp) && [event subtype] == 0) {
[seenDummyEventLock lockWhenCondition:NO];
[seenDummyEventLock unlockWithCondition:YES];
+ } else if ([event type] == NSApplicationDefined && [event subtype] == 777) {
+ void (^block)() = (void (^)()) [event data1];
+ block();
+ [block release];
} else if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask)) {
// Cocoa won't send us key up event when releasing a key while Cmd is down,
// so we have to do it ourselves.
@@ -349,6 +353,33 @@
}
}
+/*
+ * Posts the block to the AppKit event queue which will be executed
+ * on the main AppKit loop.
+ * While running nested loops this event will be ignored.
+ */
+- (void)postRunnableEvent:(void (^)())block
+{
+ void (^copy)() = [block copy];
+ NSInteger encode = (NSInteger) copy;
+ [copy retain];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSEvent* event = [NSEvent otherEventWithType: NSApplicationDefined
+ location: NSMakePoint(0,0)
+ modifierFlags: 0
+ timestamp: 0
+ windowNumber: 0
+ context: nil
+ subtype: 777
+ data1: encode
+ data2: 0];
+
+ [NSApp postEvent: event atStart: NO];
+ [pool drain];
+}
+
+
+
- (void)postDummyEvent {
seenDummyEventLock = [[NSConditionLock alloc] initWithCondition:NO];
dummyEventTimestamp = [NSProcessInfo processInfo].systemUptime;