< prev index next >

src/java.desktop/macosx/native/libosxapp/ThreadUtilities.m

Print this page
rev 54098 : 8260616: Removing remaining JNF dependencies in the java.desktop module
8259729: Missed JNFInstanceOf -> IsInstanceOf conversion

@@ -22,20 +22,21 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
 
 #import <AppKit/AppKit.h>
-#import <JavaNativeFoundation/JavaNativeFoundation.h>
 #import <objc/message.h>
 
 #import "ThreadUtilities.h"
 
 
 // The following must be named "jvm", as there are extern references to it in AWT
 JavaVM *jvm = NULL;
 static JNIEnv *appKitEnv = NULL;
 static jobject appkitThreadGroup = NULL;
+static NSString* JavaRunLoopMode = @"javaRunLoopMode";
+static NSArray<NSString*> *javaModes = nil;
 
 static inline void attachCurrentThread(void** env) {
     if ([NSThread isMainThread]) {
         JavaVMAttachArgs args;
         args.version = JNI_VERSION_1_4;

@@ -47,10 +48,19 @@
     }
 }
 
 @implementation ThreadUtilities
 
++ (void)initialize {
+    /* All the standard modes plus ours */
+    javaModes = [[NSArray alloc] initWithObjects:NSDefaultRunLoopMode,
+                                           NSModalPanelRunLoopMode,
+                                           NSEventTrackingRunLoopMode,
+                                           JavaRunLoopMode,
+                                           nil];
+}
+
 + (JNIEnv*)getJNIEnv {
 AWT_ASSERT_APPKIT_THREAD;
     if (appKitEnv == NULL) {
         attachCurrentThread((void **)&appKitEnv);
     }

@@ -69,26 +79,53 @@
 
 + (void)setAppkitThreadGroup:(jobject)group {
     appkitThreadGroup = group;
 }
 
+/* This is needed because we can't directly pass a block to
+ * performSelectorOnMainThreadWaiting .. since it expects a selector
+ */
++ (void)invokeBlock:(void (^)())block {
+  block();
+}
+
+/*
+ * When running a block where either we don't wait, or it needs to run on another thread
+ * we need to copy it from stack to heap, use the copy in the call and release after use.
+ * Do this only when we must because it could be expensive.
+ * Note : if waiting cross-thread, possibly the stack allocated copy is accessible ?
+ */
++ (void)invokeBlockCopy:(void (^)(void))blockCopy {
+  blockCopy();
+  Block_release(blockCopy);
+}
+
 + (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block {
     if ([NSThread isMainThread] && wait == YES) {
         block();
     } else {
-        [JNFRunLoop performOnMainThreadWaiting:wait withBlock:block];
+        if (wait == YES) {
+            [self performOnMainThread:@selector(invokeBlock:) on:self withObject:block waitUntilDone:YES];
+        } else {
+            void (^blockCopy)(void) = Block_copy(block);
+            [self performOnMainThread:@selector(invokeBlockCopy:) on:self withObject:blockCopy waitUntilDone:NO];
+        }
     }
 }
 
 + (void)performOnMainThread:(SEL)aSelector on:(id)target withObject:(id)arg waitUntilDone:(BOOL)wait {
     if ([NSThread isMainThread] && wait == YES) {
         [target performSelector:aSelector withObject:arg];
     } else {
-        [JNFRunLoop performOnMainThread:aSelector on:target withObject:arg waitUntilDone:wait];
+        [target performSelectorOnMainThread:aSelector withObject:arg waitUntilDone:wait modes:javaModes];
     }
 }
 
++ (NSString*)javaRunLoopMode {
+    return JavaRunLoopMode;
+}
+
 @end
 
 
 void OSXAPP_SetJavaVM(JavaVM *vm)
 {
< prev index next >