1 /*
   2  * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   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 #ifndef __THREADUTILITIES_H
  27 #define __THREADUTILITIES_H
  28 
  29 #include "jni.h"
  30 
  31 #import <pthread.h>
  32 
  33 #import "AWT_debug.h"
  34 
  35 
  36 // --------------------------------------------------------------------------
  37 #ifndef PRODUCT_BUILD
  38 
  39 // Turn on the AWT thread assert mechanism. See below for different variants.
  40 // TODO: don't enable this for production builds...
  41 #define AWT_THREAD_ASSERTS
  42 
  43 #endif /* PRODUCT_BUILD */
  44 // --------------------------------------------------------------------------
  45 
  46 // --------------------------------------------------------------------------
  47 #ifdef AWT_THREAD_ASSERTS
  48 
  49 // Turn on to have awt thread asserts display a message on the console.
  50 #define AWT_THREAD_ASSERTS_MESSAGES
  51 
  52 // Turn on to have awt thread asserts use an environment variable switch to
  53 // determine if assert should really be called.
  54 //#define AWT_THREAD_ASSERTS_ENV_ASSERT
  55 
  56 // Define AWT_THREAD_ASSERTS_WAIT to make asserts halt the asserting thread
  57 // for debugging purposes.
  58 //#define AWT_THREAD_ASSERTS_WAIT
  59 
  60 #ifdef AWT_THREAD_ASSERTS_MESSAGES
  61 
  62 #define AWT_THREAD_ASSERTS_NOT_APPKIT_MESSAGE \
  63     AWT_DEBUG_LOG(@"Not running on AppKit thread 0 when expected.")
  64 
  65 #define AWT_THREAD_ASSERTS_ON_APPKIT_MESSAGE \
  66     AWT_DEBUG_LOG(@"Running on AppKit thread 0 when not expected.")
  67 
  68 #ifdef AWT_THREAD_ASSERTS_ENV_ASSERT
  69 
  70 extern int sAWTThreadAsserts;
  71 #define AWT_THREAD_ASSERTS_ENV_ASSERT_CHECK    \
  72 do {                                           \
  73     if (sAWTThreadAsserts) {                   \
  74         NSLog(@"\tPlease run this java program again with setenv COCOA_AWT_DISABLE_THREAD_ASSERTS to proceed with a warning."); \
  75         assert(NO);                            \
  76     }                                          \
  77 } while (0)
  78 
  79 #else
  80 
  81 #define AWT_THREAD_ASSERTS_ENV_ASSERT_CHECK do {} while (0)
  82 
  83 #endif /* AWT_THREAD_ASSERTS_ENV_ASSERT */
  84 
  85 #define AWT_ASSERT_APPKIT_THREAD               \
  86 do {                                           \
  87     if (pthread_main_np() == 0) {              \
  88         AWT_THREAD_ASSERTS_NOT_APPKIT_MESSAGE; \
  89         AWT_DEBUG_BUG_REPORT_MESSAGE;          \
  90         AWT_THREAD_ASSERTS_ENV_ASSERT_CHECK;   \
  91     }                                          \
  92 } while (0)
  93 
  94 #define AWT_ASSERT_NOT_APPKIT_THREAD           \
  95 do {                                           \
  96     if (pthread_main_np() != 0) {              \
  97         AWT_THREAD_ASSERTS_ON_APPKIT_MESSAGE;  \
  98         AWT_DEBUG_BUG_REPORT_MESSAGE;          \
  99         AWT_THREAD_ASSERTS_ENV_ASSERT_CHECK;   \
 100     }                                          \
 101 } while (0)
 102 
 103 #endif /* AWT_THREAD_ASSERTS_MESSAGES */
 104 
 105 #ifdef AWT_THREAD_ASSERTS_WAIT
 106 
 107 #define AWT_ASSERT_APPKIT_THREAD      \
 108 do {                                  \
 109     while (pthread_main_np() == 0) {} \
 110 } while (0)
 111 
 112 #define AWT_ASSERT_NOT_APPKIT_THREAD  \
 113 do {                                  \
 114     while (pthread_main_np() != 0) {} \
 115 } while (0)
 116 
 117 #endif /* AWT_THREAD_ASSERTS_WAIT */
 118 
 119 #else /* AWT_THREAD_ASSERTS */
 120 
 121 #define AWT_ASSERT_APPKIT_THREAD     do {} while (0)
 122 #define AWT_ASSERT_NOT_APPKIT_THREAD do {} while (0)
 123 
 124 #endif /* AWT_THREAD_ASSERTS */
 125 // --------------------------------------------------------------------------
 126 
 127 __attribute__((visibility("default")))
 128 @interface ThreadUtilities { }
 129 
 130 + (JNIEnv*)getJNIEnv;
 131 + (JNIEnv*)getJNIEnvUncached;
 132 + (void)detachCurrentThread;
 133 + (void)setAppkitThreadGroup:(jobject)group;
 134 
 135 //Wrappers for the corresponding JNFRunLoop methods with a check for main thread
 136 + (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block;
 137 + (void)performOnMainThread:(SEL)aSelector on:(id)target withObject:(id)arg waitUntilDone:(BOOL)wait;
 138 @end
 139 
 140 JNIEXPORT void OSXAPP_SetJavaVM(JavaVM *vm);
 141 
 142 #endif /* __THREADUTILITIES_H */