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}
 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