1 // Copyright (C) 2014 The Android Open Source Project
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 #include "emugl/common/thread.h"
17 #include "emugl/common/thread_store.h"
28 ScopedLocker(pthread_mutex_t* mutex) : mMutex(mutex) {
29 pthread_mutex_lock(mMutex);
33 pthread_mutex_unlock(mMutex);
36 pthread_mutex_t* mMutex;
42 mThread((pthread_t)NULL),
47 pthread_mutex_init(&mLock, NULL);
53 pthread_mutex_destroy(&mLock);
56 bool Thread::start() {
58 pthread_mutex_lock(&mLock);
60 if (pthread_create(&mThread, NULL, thread_main, this)) {
64 pthread_mutex_unlock(&mLock);
68 bool Thread::wait(intptr_t *exitStatus) {
70 ScopedLocker locker(&mLock);
72 // Thread already stopped.
74 *exitStatus = mExitStatus;
77 // reclaim thread stack
78 pthread_join(mThread, NULL);
85 // NOTE: Do not hold the lock when waiting for the thread to ensure
86 // it can update mIsRunning and mExitStatus properly in thread_main
89 if (pthread_join(mThread, &retval)) {
93 *exitStatus = (intptr_t)retval;
95 // Note: Updating mJoined must be performed inside the lock to avoid
96 // race conditions between two threads waiting for the same thread
97 // that just completed its execution.
99 ScopedLocker locker(&mLock);
105 bool Thread::tryWait(intptr_t *exitStatus) {
106 ScopedLocker locker(&mLock);
112 pthread_join(mThread, NULL);
116 *exitStatus = mExitStatus;
122 void* Thread::thread_main(void *arg) {
123 Thread* self = reinterpret_cast<Thread*>(arg);
124 intptr_t ret = self->main();
126 pthread_mutex_lock(&self->mLock);
127 self->mIsRunning = false;
128 self->mExitStatus = ret;
129 pthread_mutex_unlock(&self->mLock);
131 ::emugl::ThreadStore::OnThreadExit();