1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| void Thread::CreateNativeThread(JNIEnv* env, jobject java_peer, size_t stack_size, bool is_daemon) { CHECK(java_peer != nullptr); Thread* self = static_cast<JNIEnvExt*>(env)->GetSelf();
Runtime* runtime = Runtime::Current();
bool thread_start_during_shutdown = false; { MutexLock mu(self, *Locks::runtime_shutdown_lock_); if (runtime->IsShuttingDownLocked()) { thread_start_during_shutdown = true; } else { runtime->StartThreadBirth(); } } if (thread_start_during_shutdown) { ScopedLocalRef<jclass> error_class(env, env->FindClass("java/lang/InternalError")); env->ThrowNew(error_class.get(), "Thread starting during runtime shutdown"); return; }
Thread* child_thread = new Thread(is_daemon); child_thread->tlsPtr_.jpeer = env->NewGlobalRef(java_peer); stack_size = FixStackSize(stack_size); env->SetLongField(java_peer, WellKnownClasses::java_lang_Thread_nativePeer, reinterpret_cast<jlong>(child_thread));
std::string error_msg; std::unique_ptr<JNIEnvExt> child_jni_env_ext( JNIEnvExt::Create(child_thread, Runtime::Current()->GetJavaVM(), &error_msg));
int pthread_create_result = 0; if (child_jni_env_ext.get() != nullptr) { pthread_t new_pthread; pthread_attr_t attr; child_thread->tlsPtr_.tmp_jni_env = child_jni_env_ext.get(); CHECK_PTHREAD_CALL(pthread_attr_init, (&attr), "new thread"); CHECK_PTHREAD_CALL(pthread_attr_setdetachstate, (&attr, PTHREAD_CREATE_DETACHED), "PTHREAD_CREATE_DETACHED"); CHECK_PTHREAD_CALL(pthread_attr_setstacksize, (&attr, stack_size), stack_size); pthread_create_result = pthread_create(&new_pthread, &attr, Thread::CreateCallback, child_thread); CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attr), "new thread"); if (pthread_create_result == 0) { child_jni_env_ext.release(); return; } } }
|