cAudio  2.3.0
3d Audio Engine
 All Classes Namespaces Functions Variables Enumerations Pages
cThread.cpp
1 // Copyright (c) 2008-2011 Raynaldo (Wildicv) Rivera, Joshua (Dark_Kilauea) Jones, Murat (wolfmanfx) Sari
2 // This file is part of the "cAudio Engine"
3 // For conditions of distribution and use, see copyright notice in cAudio.h
4 
5 #include "cThread.h"
6 #include "cAudioSleep.h"
7 
8 namespace cAudio
9 {
10  cAudioThread::cAudioThread(IThreadWorker* pWorker) : ThreadHandle(0), Worker(pWorker), ThreadID(0), IsInit(false), Loop(true)
11  {
12  }
13 
14  cAudioThread::~cAudioThread()
15  {
16  }
17 
18  bool cAudioThread::start()
19  {
20  cAudioMutexBasicLock lock(Mutex);
21 
22  if(IsInit)
23  return IsInit;
24 
25  IsInit = true;
26 
27 #ifdef CAUDIO_PLATFORM_WIN
28  ThreadHandle = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, threadFunc, this, 0, &ThreadID));
29 #else
30  pthread_create( &ThreadHandle, 0, threadFunc, this );
31 #endif
32  IsInit = ThreadHandle != 0;
33  return IsInit;
34  }
35  void cAudioThread::join()
36  {
37  cAudioMutexBasicLock lock(Mutex);
38  if(IsInit)
39  {
40  Loop = false;
41 #ifdef CAUDIO_PLATFORM_WIN
42  WaitForSingleObject(ThreadHandle, INFINITE);
43 #else
44  pthread_join(ThreadHandle, NULL);
45 #endif
46  }
47  }
48  void cAudioThread::shutdown()
49  {
50  cAudioMutexBasicLock lock(Mutex);
51  if(IsInit)
52  {
53  IsInit = false;
54 #ifdef CAUDIO_PLATFORM_WIN
55  _endthread();
56 #else
57  pthread_exit(0);
58 #endif
59  }
60  }
61  void cAudioThread::updateLoop()
62  {
63  if(IsInit && Worker)
64  {
65  while (Loop)
66  {
67  Worker->run();
68  }
69  }
70  }
71 
72  bool cAudioThread::isRunning()
73  {
74  return Loop && IsInit;
75  }
76 
77 #ifdef CAUDIO_PLATFORM_WIN
78 
79  //
80  // Usage: SetThreadName (-1, "MainThread");
81  //
82  const DWORD MS_VC_EXCEPTION = 0x406D1388;
83 
84 #pragma pack(push,8)
85  typedef struct tagTHREADNAME_INFO
86  {
87  DWORD dwType; // Must be 0x1000.
88  LPCSTR szName; // Pointer to name (in user addr space).
89  DWORD dwThreadID; // Thread ID (-1=caller thread).
90  DWORD dwFlags; // Reserved for future use, must be zero.
91  } THREADNAME_INFO;
92 #pragma pack(pop)
93 
94  inline void SetThreadName(DWORD dwThreadID, const char* threadName)
95  {
96  THREADNAME_INFO info;
97  info.dwType = 0x1000;
98  info.szName = threadName;
99  info.dwThreadID = dwThreadID;
100  info.dwFlags = 0;
101 
102  __try
103  {
104  RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
105  }
106  __except (EXCEPTION_EXECUTE_HANDLER)
107  {
108  }
109  }
110 
111  unsigned int __stdcall cAudioThread::threadFunc(void *args)
112  {
113  cAudioThread* pThread = reinterpret_cast<cAudioThread*>(args);
114  SetThreadName(GetCurrentThreadId(), "cAudio");
115  pThread->updateLoop();
116  return 0;
117  }
118 #else
119  void* cAudioThread::threadFunc(void* args)
120  {
121  cAudioThread* pThread = reinterpret_cast<cAudioThread*>(args);
122 #if defined(CAUDIO_PLATFORM_MAC) || defined(CAUDIO_PLATFORM_IPHONE)
123  pthread_setname_np("cAudio");
124 #else
125  pthread_setname_np(pthread_self(), "cAudio");
126 #endif
127  pThread->updateLoop();
128  return 0;
129  }
130 #endif
131 };