status_t Thread::run(const char* name, int32_t priority, size_t stack) { Mutex::Autolock _l(mLock); if (mRunning) { // thread already started return INVALID_OPERATION; } // reset status and exitPending to their default value, so we can // try again after an error happened (either below, or in readyToRun()) mStatus = NO_ERROR; mExitPending = false; mThread = thread_id_t(-1); // hold a strong reference on ourself mHoldSelf = this; mRunning = true; bool res; if (mCanCallJava) { res = createThreadEtc(_threadLoop, this, name, priority, stack, &mThread); } else { res = androidCreateRawThreadEtc(_threadLoop, this, name, priority, stack, &mThread); } if (res == false) { mStatus = UNKNOWN_ERROR; // something happened! mRunning = false; mThread = thread_id_t(-1); mHoldSelf.clear(); // "this" may have gone away after this. return UNKNOWN_ERROR; } // Do not refer to mStatus here: The thread is already running (may, in fact // already have exited with a valid mStatus result). The NO_ERROR indication // here merely indicates successfully starting the thread and does not // imply successful termination/execution. return NO_ERROR; // Exiting scope of mLock is a memory barrier and allows new thread to run }
/* * This is invoked from androidCreateThreadEtc() via the callback * set with androidSetCreateThreadFunc(). * * We need to create the new thread in such a way that it gets hooked * into the VM before it really starts executing. */ /*static*/ int AndroidRuntime::javaCreateThreadEtc( android_thread_func_t entryFunction, void* userData, const char* threadName, int32_t threadPriority, size_t threadStackSize, android_thread_id_t* threadId) { void** args = (void**) malloc(3 * sizeof(void*)); // javaThreadShell must free int result; assert(threadName != NULL); args[0] = (void*) entryFunction; args[1] = userData; args[2] = (void*) strdup(threadName); // javaThreadShell must free result = androidCreateRawThreadEtc(AndroidRuntime::javaThreadShell, args, threadName, threadPriority, threadStackSize, threadId); return result; }