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 shouldStop = true; 88} 89 90Thread::~Thread() 91{ 92 stop(); 93 if( isAlive() ) 94 join(); 95 96 97 delete mData; 98} 99 100void Thread::start( void* arg ) 101{ 102 // cause start to block out other pthreads from using this Thread, 103 // at least until ThreadRunHandler exits. 104 mData->mGateway.acquire(); 105 106 // reset the shouldStop flag, so we'll know when someone asks us to stop. 107 shouldStop = false; 108 109 mData->mDead = false; 110 111 if( !mData->mRunArg ) 112 mData->mRunArg = arg; 113 114 mData->mSdlThread = SDL_CreateThread(ThreadRunHandler,NULL,mData); 115 116} 117 118bool Thread::join() 119{ 120 mData->mGateway.acquire(); 121 AssertFatal( !isAlive(), "Thread::join() - thread not dead after join()" ); 122 mData->mGateway.release(); 123 124 return true; 125} 126 127void Thread::run(void* arg) 128{ 129 if(mData->mRunFunc) 130 mData->mRunFunc(arg); 131} 132 133bool Thread::isAlive() 134{ 135 return ( !mData->mDead ); 136} 137 138U32 Thread::getId() 139{ 140 return (U32)mData->mThreadID; 141} 142 143void Thread::_setName( const char* ) 144{ 145 // Not supported. Wading through endless lists of Thread-1, Thread-2, Thread-3, ... trying to find 146 // that one thread you are looking for is just so much fun. 147} 148 149U32 ThreadManager::getCurrentThreadId() 150{ 151 return (U32)SDL_ThreadID(); 152} 153 154bool ThreadManager::compare(U32 threadId_1, U32 threadId_2) 155{ 156 return (threadId_1 == threadId_2); 157} 158