thread.cpp
Engine/source/platformSDL/threads/thread.cpp
Classes:
class
Public Functions
int
ThreadRunHandler(void * arg)
Detailed Description
Public Functions
ThreadRunHandler(void * arg)
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/threads/thread.h" 25#include "platform/threads/semaphore.h" 26#include "platform/threads/mutex.h" 27#include <stdlib.h> 28#include <SDL.h> 29#include <SDL_thread.h> 30 31class PlatformThreadData 32{ 33public: 34 ThreadRunFunction mRunFunc; 35 void* mRunArg; 36 Thread* mThread; 37 Semaphore mGateway; // default count is 1 38 SDL_threadID mThreadID; 39 SDL_Thread* mSdlThread; 40 bool mDead; 41}; 42 43ThreadManager::MainThreadId ThreadManager::smMainThreadId; 44 45//----------------------------------------------------------------------------- 46// Function: ThreadRunHandler 47// Summary: Calls Thread::run() with the thread's specified run argument. 48// Neccesary because Thread::run() is provided as a non-threaded 49// way to execute the thread's run function. So we have to keep 50// track of the thread's lock here. 51static int ThreadRunHandler(void * arg) 52{ 53 PlatformThreadData *mData = reinterpret_cast<PlatformThreadData*>(arg); 54 Thread *thread = mData->mThread; 55 56 mData->mThreadID = SDL_ThreadID(); 57 58 ThreadManager::addThread(thread); 59 thread->run(mData->mRunArg); 60 ThreadManager::removeThread(thread); 61 62 bool autoDelete = thread->autoDelete; 63 64 mData->mThreadID = 0; 65 mData->mDead = true; 66 mData->mGateway.release(); 67 68 if( autoDelete ) 69 delete thread; 70 71 return 0; 72} 73 74//----------------------------------------------------------------------------- 75Thread::Thread(ThreadRunFunction func, void* arg, bool start_thread, bool autodelete) 76{ 77 AssertFatal( !start_thread, "Thread::Thread() - auto-starting threads from ctor has been disallowed since the run() method is virtual" ); 78 79 mData = new PlatformThreadData; 80 mData->mRunFunc = func; 81 mData->mRunArg = arg; 82 mData->mThread = this; 83 mData->mThreadID = 0; 84 mData->mDead = false; 85 mData->mSdlThread = NULL; 86 autoDelete = autodelete; 87} 88 89Thread::~Thread() 90{ 91 stop(); 92 if( isAlive() ) 93 join(); 94 95 96 delete mData; 97} 98 99void Thread::start( void* arg ) 100{ 101 // cause start to block out other pthreads from using this Thread, 102 // at least until ThreadRunHandler exits. 103 mData->mGateway.acquire(); 104 105 // reset the shouldStop flag, so we'll know when someone asks us to stop. 106 shouldStop = false; 107 108 mData->mDead = false; 109 110 if( !mData->mRunArg ) 111 mData->mRunArg = arg; 112 113 mData->mSdlThread = SDL_CreateThread(ThreadRunHandler,NULL,mData); 114 115} 116 117bool Thread::join() 118{ 119 mData->mGateway.acquire(); 120 AssertFatal( !isAlive(), "Thread::join() - thread not dead after join()" ); 121 mData->mGateway.release(); 122 123 return true; 124} 125 126void Thread::run(void* arg) 127{ 128 if(mData->mRunFunc) 129 mData->mRunFunc(arg); 130} 131 132bool Thread::isAlive() 133{ 134 return ( !mData->mDead ); 135} 136 137U32 Thread::getId() 138{ 139 return (U32)mData->mThreadID; 140} 141 142void Thread::_setName( const char* ) 143{ 144 // Not supported. Wading through endless lists of Thread-1, Thread-2, Thread-3, ... trying to find 145 // that one thread you are looking for is just so much fun. 146} 147 148U32 ThreadManager::getCurrentThreadId() 149{ 150 return (U32)SDL_ThreadID(); 151} 152 153bool ThreadManager::compare(U32 threadId_1, U32 threadId_2) 154{ 155 return (threadId_1 == threadId_2); 156} 157
