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