thread.cpp

Engine/source/platformSDL/threads/thread.cpp

More...

Classes:

Public Functions

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