src/core/android/SDL_android.c
changeset 8055 3e2f230a6d62
parent 8047 a5270cef21a7
child 8057 801d84e26f91
equal deleted inserted replaced
8054:2a38ef3eeabb 8055:3e2f230a6d62
    96     }
    96     }
    97     /*
    97     /*
    98      * Create mThreadKey so we can keep track of the JNIEnv assigned to each thread
    98      * Create mThreadKey so we can keep track of the JNIEnv assigned to each thread
    99      * Refer to http://developer.android.com/guide/practices/design/jni.html for the rationale behind this
    99      * Refer to http://developer.android.com/guide/practices/design/jni.html for the rationale behind this
   100      */
   100      */
   101     if (pthread_key_create(&mThreadKey, Android_JNI_ThreadDestroyed)) {
   101     if (pthread_key_create(&mThreadKey, Android_JNI_ThreadDestroyed) != 0) {
   102         __android_log_print(ANDROID_LOG_ERROR, "SDL", "Error initializing pthread key");
   102         __android_log_print(ANDROID_LOG_ERROR, "SDL", "Error initializing pthread key");
   103     }
   103     }
   104     else {
   104     Android_JNI_SetupThread();
   105         Android_JNI_SetupThread();
       
   106     }
       
   107 
   105 
   108     return JNI_VERSION_1_4;
   106     return JNI_VERSION_1_4;
   109 }
   107 }
   110 
   108 
   111 /* Called before SDL_main() to initialize JNI bindings */
   109 /* Called before SDL_main() to initialize JNI bindings */
   452     }
   450     }
   453 
   451 
   454     return retval;
   452     return retval;
   455 }
   453 }
   456 
   454 
   457 static void Android_JNI_ThreadDestroyed(void* value) {
   455 static void Android_JNI_ThreadDestroyed(void* value)
       
   456 {
   458     /* The thread is being destroyed, detach it from the Java VM and set the mThreadKey value to NULL as required */
   457     /* The thread is being destroyed, detach it from the Java VM and set the mThreadKey value to NULL as required */
   459     JNIEnv *env = (JNIEnv*) value;
   458     JNIEnv *env = (JNIEnv*) value;
   460     if (env != NULL) {
   459     if (env != NULL) {
   461         (*mJavaVM)->DetachCurrentThread(mJavaVM);
   460         (*mJavaVM)->DetachCurrentThread(mJavaVM);
   462         pthread_setspecific(mThreadKey, NULL);
   461         pthread_setspecific(mThreadKey, NULL);
   463     }
   462     }
   464 }
   463 }
   465 
   464 
   466 JNIEnv* Android_JNI_GetEnv(void) {
   465 JNIEnv* Android_JNI_GetEnv(void)
       
   466 {
   467     /* From http://developer.android.com/guide/practices/jni.html
   467     /* From http://developer.android.com/guide/practices/jni.html
   468      * All threads are Linux threads, scheduled by the kernel.
   468      * All threads are Linux threads, scheduled by the kernel.
   469      * They're usually started from managed code (using Thread.start), but they can also be created elsewhere and then
   469      * They're usually started from managed code (using Thread.start), but they can also be created elsewhere and then
   470      * attached to the JavaVM. For example, a thread started with pthread_create can be attached with the
   470      * attached to the JavaVM. For example, a thread started with pthread_create can be attached with the
   471      * JNI AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a thread is attached, it has no JNIEnv,
   471      * JNI AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a thread is attached, it has no JNIEnv,
   481     if(status < 0) {
   481     if(status < 0) {
   482         LOGE("failed to attach current thread");
   482         LOGE("failed to attach current thread");
   483         return 0;
   483         return 0;
   484     }
   484     }
   485 
   485 
   486     return env;
       
   487 }
       
   488 
       
   489 int Android_JNI_SetupThread(void) {
       
   490     /* From http://developer.android.com/guide/practices/jni.html
   486     /* From http://developer.android.com/guide/practices/jni.html
   491      * Threads attached through JNI must call DetachCurrentThread before they exit. If coding this directly is awkward,
   487      * Threads attached through JNI must call DetachCurrentThread before they exit. If coding this directly is awkward,
   492      * in Android 2.0 (Eclair) and higher you can use pthread_key_create to define a destructor function that will be
   488      * in Android 2.0 (Eclair) and higher you can use pthread_key_create to define a destructor function that will be
   493      * called before the thread exits, and call DetachCurrentThread from there. (Use that key with pthread_setspecific
   489      * called before the thread exits, and call DetachCurrentThread from there. (Use that key with pthread_setspecific
   494      * to store the JNIEnv in thread-local-storage; that way it'll be passed into your destructor as the argument.)
   490      * to store the JNIEnv in thread-local-storage; that way it'll be passed into your destructor as the argument.)
   495      * Note: The destructor is not called unless the stored value is != NULL
   491      * Note: The destructor is not called unless the stored value is != NULL
   496      * Note: You can call this function any number of times for the same thread, there's no harm in it
   492      * Note: You can call this function any number of times for the same thread, there's no harm in it
   497      *       (except for some lost CPU cycles)
   493      *       (except for some lost CPU cycles)
   498      */
   494      */
   499     JNIEnv *env = Android_JNI_GetEnv();
       
   500     pthread_setspecific(mThreadKey, (void*) env);
   495     pthread_setspecific(mThreadKey, (void*) env);
       
   496 
       
   497     return env;
       
   498 }
       
   499 
       
   500 int Android_JNI_SetupThread(void)
       
   501 {
       
   502     Android_JNI_GetEnv();
   501     return 1;
   503     return 1;
   502 }
   504 }
   503 
   505 
   504 /*
   506 /*
   505  * Audio support
   507  * Audio support