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"
25 ScopedLocker(CRITICAL_SECTION* section) : mSection(section) {
26 EnterCriticalSection(mSection);
30 LeaveCriticalSection(mSection);
33 CRITICAL_SECTION* mSection;
39 mThread(INVALID_HANDLE_VALUE),
43 InitializeCriticalSection(&mLock);
47 if(mThread != INVALID_HANDLE_VALUE) {
50 DeleteCriticalSection(&mLock);
53 bool Thread::start() {
54 ScopedLocker locker(&mLock);
58 mThread = CreateThread(NULL, 0, &Thread::thread_main, this, 0, &mThreadId);
66 bool Thread::wait(intptr_t* exitStatus) {
68 ScopedLocker locker(&mLock);
70 // Thread already stopped.
72 *exitStatus = mExitStatus;
78 // NOTE: Do not hold lock during wait to aloow thread_main to
79 // properly update mIsRunning and mExitStatus on thread exit.
80 if (WaitForSingleObject(mThread, INFINITE) == WAIT_FAILED) {
85 ScopedLocker locker(&mLock);
86 *exitStatus = mExitStatus;
91 bool Thread::tryWait(intptr_t* exitStatus) {
92 ScopedLocker locker(&mLock);
94 if (mIsRunning && WaitForSingleObject(mThread, 0) != WAIT_OBJECT_0) {
99 *exitStatus = mExitStatus;
105 DWORD WINAPI Thread::thread_main(void *arg)
107 Thread* self = reinterpret_cast<Thread*>(arg);
108 intptr_t ret = self->main();
110 EnterCriticalSection(&self->mLock);
111 self->mIsRunning = false;
112 self->mExitStatus = ret;
113 LeaveCriticalSection(&self->mLock);
115 // Ensure all thread-local values are released for this thread.
116 ::emugl::ThreadStore::OnThreadExit();
118 return static_cast<DWORD>(ret);