jdk/src/jdk.deploy.osx/macosx/native/libosx/Dispatch.m
changeset 36605 59b58343d358
parent 36604 e9c073b0c19e
parent 36567 03a6f39ebb73
child 36606 8167f548e63c
child 36607 dc9021790941
equal deleted inserted replaced
36604:e9c073b0c19e 36605:59b58343d358
     1 /*
       
     2  * Copyright (c) 2011, 2015, 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 /*
       
    27  * Must include this before JavaNativeFoundation.h to get jni.h from build
       
    28  */
       
    29 #include "jni.h"
       
    30 #include "jni_util.h"
       
    31 
       
    32 #import "com_apple_concurrent_LibDispatchNative.h"
       
    33 
       
    34 #import <dispatch/dispatch.h>
       
    35 #import <JavaNativeFoundation/JavaNativeFoundation.h>
       
    36 
       
    37 /*
       
    38  * Declare library specific JNI_Onload entry if static build
       
    39  */
       
    40 DEF_STATIC_JNI_OnLoad
       
    41 
       
    42 /*
       
    43  * Class:     com_apple_concurrent_LibDispatchNative
       
    44  * Method:    nativeIsDispatchSupported
       
    45  * Signature: ()Z
       
    46  */
       
    47 JNIEXPORT jboolean JNICALL Java_com_apple_concurrent_LibDispatchNative_nativeIsDispatchSupported
       
    48 (JNIEnv *env, jclass clazz)
       
    49 {
       
    50         return JNI_TRUE;
       
    51 }
       
    52 
       
    53 
       
    54 /*
       
    55  * Class:     com_apple_concurrent_LibDispatchNative
       
    56  * Method:    nativeGetMainQueue
       
    57  * Signature: ()J
       
    58  */
       
    59 JNIEXPORT jlong JNICALL Java_com_apple_concurrent_LibDispatchNative_nativeGetMainQueue
       
    60 (JNIEnv *env, jclass clazz)
       
    61 {
       
    62         dispatch_queue_t queue = dispatch_get_main_queue();
       
    63         return ptr_to_jlong(queue);
       
    64 }
       
    65 
       
    66 
       
    67 /*
       
    68  * Class:     com_apple_concurrent_LibDispatchNative
       
    69  * Method:    nativeCreateConcurrentQueue
       
    70  * Signature: (I)J
       
    71  */
       
    72 JNIEXPORT jlong JNICALL Java_com_apple_concurrent_LibDispatchNative_nativeCreateConcurrentQueue
       
    73 (JNIEnv *env, jclass clazz, jint priority)
       
    74 {
       
    75         dispatch_queue_t queue = dispatch_get_global_queue((long)priority, 0);
       
    76         return ptr_to_jlong(queue);
       
    77 }
       
    78 
       
    79 
       
    80 /*
       
    81  * Class:     com_apple_concurrent_LibDispatchNative
       
    82  * Method:    nativeCreateSerialQueue
       
    83  * Signature: (Ljava/lang/String;)J
       
    84  */
       
    85 JNIEXPORT jlong JNICALL Java_com_apple_concurrent_LibDispatchNative_nativeCreateSerialQueue
       
    86 (JNIEnv *env, jclass clazz, jstring name)
       
    87 {
       
    88         if (name == NULL) return 0L;
       
    89 
       
    90         jboolean isCopy;
       
    91         const char *queue_name = (*env)->GetStringUTFChars(env, name, &isCopy);
       
    92         dispatch_queue_t queue = dispatch_queue_create(queue_name, NULL);
       
    93         (*env)->ReleaseStringUTFChars(env, name, queue_name);
       
    94 
       
    95         return ptr_to_jlong(queue);
       
    96 }
       
    97 
       
    98 
       
    99 /*
       
   100  * Class:     com_apple_concurrent_LibDispatchNative
       
   101  * Method:    nativeReleaseQueue
       
   102  * Signature: (J)V
       
   103  */
       
   104 JNIEXPORT void JNICALL Java_com_apple_concurrent_LibDispatchNative_nativeReleaseQueue
       
   105 (JNIEnv *env, jclass clazz, jlong nativeQueue)
       
   106 {
       
   107         if (nativeQueue == 0L) return;
       
   108         dispatch_release((dispatch_queue_t)jlong_to_ptr(nativeQueue));
       
   109 }
       
   110 
       
   111 
       
   112 static JNF_CLASS_CACHE(jc_Runnable, "java/lang/Runnable");
       
   113 static JNF_MEMBER_CACHE(jm_run, jc_Runnable, "run", "()V");
       
   114 
       
   115 static void perform_dispatch(JNIEnv *env, jlong nativeQueue, jobject runnable, void (*dispatch_fxn)(dispatch_queue_t, dispatch_block_t))
       
   116 {
       
   117 JNF_COCOA_ENTER(env);
       
   118         dispatch_queue_t queue = (dispatch_queue_t)jlong_to_ptr(nativeQueue);
       
   119         if (queue == NULL) return; // shouldn't happen
       
   120 
       
   121         // create a global-ref around the Runnable, so it can be safely passed to the dispatch thread
       
   122         JNFJObjectWrapper *wrappedRunnable = [[JNFJObjectWrapper alloc] initWithJObject:runnable withEnv:env];
       
   123 
       
   124         dispatch_fxn(queue, ^{
       
   125                 // attach the dispatch thread to the JVM if necessary, and get an env
       
   126                 JNFThreadContext ctx = JNFThreadDetachOnThreadDeath | JNFThreadSetSystemClassLoaderOnAttach | JNFThreadAttachAsDaemon;
       
   127                 JNIEnv *blockEnv = JNFObtainEnv(&ctx);
       
   128 
       
   129         JNF_COCOA_ENTER(blockEnv);
       
   130 
       
   131                 // call the user's runnable
       
   132                 JNFCallObjectMethod(blockEnv, [wrappedRunnable jObject], jm_run);
       
   133 
       
   134                 // explicitly clear object while we have an env (it's cheaper that way)
       
   135                 [wrappedRunnable setJObject:NULL withEnv:blockEnv];
       
   136 
       
   137         JNF_COCOA_EXIT(blockEnv);
       
   138 
       
   139                 // let the env go, but leave the thread attached as a daemon
       
   140                 JNFReleaseEnv(blockEnv, &ctx);
       
   141         });
       
   142 
       
   143         // release this thread's interest in the Runnable, the block
       
   144         // will have retained the it's own interest above
       
   145         [wrappedRunnable release];
       
   146 
       
   147 JNF_COCOA_EXIT(env);
       
   148 }
       
   149 
       
   150 
       
   151 /*
       
   152  * Class:     com_apple_concurrent_LibDispatchNative
       
   153  * Method:    nativeExecuteAsync
       
   154  * Signature: (JLjava/lang/Runnable;)V
       
   155  */
       
   156 JNIEXPORT void JNICALL Java_com_apple_concurrent_LibDispatchNative_nativeExecuteAsync
       
   157 (JNIEnv *env, jclass clazz, jlong nativeQueue, jobject runnable)
       
   158 {
       
   159         // enqueues and returns
       
   160         perform_dispatch(env, nativeQueue, runnable, dispatch_async);
       
   161 }
       
   162 
       
   163 
       
   164 /*
       
   165  * Class:     com_apple_concurrent_LibDispatchNative
       
   166  * Method:    nativeExecuteSync
       
   167  * Signature: (JLjava/lang/Runnable;)V
       
   168  */
       
   169 JNIEXPORT void JNICALL Java_com_apple_concurrent_LibDispatchNative_nativeExecuteSync
       
   170 (JNIEnv *env, jclass clazz, jlong nativeQueue, jobject runnable)
       
   171 {
       
   172         // blocks until the Runnable completes
       
   173         perform_dispatch(env, nativeQueue, runnable, dispatch_sync);
       
   174 }