7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #import <AppKit/AppKit.h>
27 #import <JavaNativeFoundation/JavaNativeFoundation.h>
28 #import <objc/message.h>
29
30 #import "ThreadUtilities.h"
31
32
33 // The following must be named "jvm", as there are extern references to it in AWT
34 JavaVM *jvm = NULL;
35 static JNIEnv *appKitEnv = NULL;
36 static jobject appkitThreadGroup = NULL;
37
38 static inline void attachCurrentThread(void** env) {
39 if ([NSThread isMainThread]) {
40 JavaVMAttachArgs args;
41 args.version = JNI_VERSION_1_4;
42 args.name = "AppKit Thread";
43 args.group = appkitThreadGroup;
44 (*jvm)->AttachCurrentThreadAsDaemon(jvm, env, &args);
45 } else {
46 (*jvm)->AttachCurrentThreadAsDaemon(jvm, env, NULL);
47 }
48 }
49
50 @implementation ThreadUtilities
51
52 + (JNIEnv*)getJNIEnv {
53 AWT_ASSERT_APPKIT_THREAD;
54 if (appKitEnv == NULL) {
55 attachCurrentThread((void **)&appKitEnv);
56 }
57 return appKitEnv;
58 }
59
60 + (JNIEnv*)getJNIEnvUncached {
61 JNIEnv *env = NULL;
62 attachCurrentThread((void **)&env);
63 return env;
64 }
65
66 + (void)detachCurrentThread {
67 (*jvm)->DetachCurrentThread(jvm);
68 }
69
70 + (void)setAppkitThreadGroup:(jobject)group {
71 appkitThreadGroup = group;
72 }
73
74 + (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block {
75 if ([NSThread isMainThread] && wait == YES) {
76 block();
77 } else {
78 [JNFRunLoop performOnMainThreadWaiting:wait withBlock:block];
79 }
80 }
81
82 + (void)performOnMainThread:(SEL)aSelector on:(id)target withObject:(id)arg waitUntilDone:(BOOL)wait {
83 if ([NSThread isMainThread] && wait == YES) {
84 [target performSelector:aSelector withObject:arg];
85 } else {
86 [JNFRunLoop performOnMainThread:aSelector on:target withObject:arg waitUntilDone:wait];
87 }
88 }
89
90 @end
91
92
93 void OSXAPP_SetJavaVM(JavaVM *vm)
94 {
95 jvm = vm;
96 }
97
|
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #import <AppKit/AppKit.h>
27 #import <objc/message.h>
28
29 #import "ThreadUtilities.h"
30
31
32 // The following must be named "jvm", as there are extern references to it in AWT
33 JavaVM *jvm = NULL;
34 static JNIEnv *appKitEnv = NULL;
35 static jobject appkitThreadGroup = NULL;
36 static NSString* JavaRunLoopMode = @"javaRunLoopMode";
37 static NSArray<NSString*> *javaModes = nil;
38
39 static inline void attachCurrentThread(void** env) {
40 if ([NSThread isMainThread]) {
41 JavaVMAttachArgs args;
42 args.version = JNI_VERSION_1_4;
43 args.name = "AppKit Thread";
44 args.group = appkitThreadGroup;
45 (*jvm)->AttachCurrentThreadAsDaemon(jvm, env, &args);
46 } else {
47 (*jvm)->AttachCurrentThreadAsDaemon(jvm, env, NULL);
48 }
49 }
50
51 @implementation ThreadUtilities
52
53 + (void)initialize {
54 /* All the standard modes plus ours */
55 javaModes = [[NSArray alloc] initWithObjects:NSDefaultRunLoopMode,
56 NSModalPanelRunLoopMode,
57 NSEventTrackingRunLoopMode,
58 JavaRunLoopMode,
59 nil];
60 }
61
62 + (JNIEnv*)getJNIEnv {
63 AWT_ASSERT_APPKIT_THREAD;
64 if (appKitEnv == NULL) {
65 attachCurrentThread((void **)&appKitEnv);
66 }
67 return appKitEnv;
68 }
69
70 + (JNIEnv*)getJNIEnvUncached {
71 JNIEnv *env = NULL;
72 attachCurrentThread((void **)&env);
73 return env;
74 }
75
76 + (void)detachCurrentThread {
77 (*jvm)->DetachCurrentThread(jvm);
78 }
79
80 + (void)setAppkitThreadGroup:(jobject)group {
81 appkitThreadGroup = group;
82 }
83
84 /* This is needed because we can't directly pass a block to
85 * performSelectorOnMainThreadWaiting .. since it expects a selector
86 */
87 + (void)invokeBlock:(void (^)())block {
88 block();
89 }
90
91 /*
92 * When running a block where either we don't wait, or it needs to run on another thread
93 * we need to copy it from stack to heap, use the copy in the call and release after use.
94 * Do this only when we must because it could be expensive.
95 * Note : if waiting cross-thread, possibly the stack allocated copy is accessible ?
96 */
97 + (void)invokeBlockCopy:(void (^)(void))blockCopy {
98 blockCopy();
99 Block_release(blockCopy);
100 }
101
102 + (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block {
103 if ([NSThread isMainThread] && wait == YES) {
104 block();
105 } else {
106 if (wait == YES) {
107 [self performOnMainThread:@selector(invokeBlock:) on:self withObject:block waitUntilDone:YES];
108 } else {
109 void (^blockCopy)(void) = Block_copy(block);
110 [self performOnMainThread:@selector(invokeBlockCopy:) on:self withObject:blockCopy waitUntilDone:NO];
111 }
112 }
113 }
114
115 + (void)performOnMainThread:(SEL)aSelector on:(id)target withObject:(id)arg waitUntilDone:(BOOL)wait {
116 if ([NSThread isMainThread] && wait == YES) {
117 [target performSelector:aSelector withObject:arg];
118 } else {
119 [target performSelectorOnMainThread:aSelector withObject:arg waitUntilDone:wait modes:javaModes];
120 }
121 }
122
123 + (NSString*)javaRunLoopMode {
124 return JavaRunLoopMode;
125 }
126
127 @end
128
129
130 void OSXAPP_SetJavaVM(JavaVM *vm)
131 {
132 jvm = vm;
133 }
134
|