Thread.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. #include "Thread.h"
  2. #include "Globals.h"
  3. using namespace Framework;
  4. // inhalt der Thread Klasse aus Thread.h
  5. // Konstruktor
  6. Thread::Thread()
  7. {
  8. threadHandleSys = 0;
  9. threadHandle = 0;
  10. threadId = 0;
  11. thRegister->add( this );
  12. run = 0;
  13. lockCount = 0;
  14. ref = 1;
  15. }
  16. // Destruktor
  17. Thread::~Thread()
  18. {
  19. thRegister->remove( this );
  20. #ifdef WIN32
  21. if( threadHandle != 0 && GetCurrentThreadId() == GetThreadId( threadHandle ) )
  22. return;
  23. #else
  24. if( pthread_self() == threadHandle )
  25. return;
  26. #endif
  27. if( run )
  28. warteAufThread( 100000 );
  29. if( run )
  30. ende();
  31. }
  32. // nicht constant
  33. void Thread::start() // startet den Thread
  34. {
  35. if( !run )
  36. {
  37. #ifdef WIN32
  38. threadHandle = CreateThread( 0, 0, threadStart, this, 0, &threadId );
  39. ref++;
  40. #else
  41. pthread_create( &threadHandle, NULL, threadStart, this );
  42. #endif
  43. }
  44. run = 1;
  45. }
  46. #ifdef WIN32
  47. void Thread::pause() // pausiert den Thread
  48. {
  49. if( run )
  50. SuspendThread( threadHandle );
  51. run = 0;
  52. }
  53. void Thread::fortsetzen() // pausiert den Thread
  54. {
  55. if( !run )
  56. ResumeThread( threadHandle );
  57. run = 1;
  58. }
  59. #endif
  60. void Thread::ende() // beendet den Thread
  61. {
  62. if( run )
  63. {
  64. while( lockCount > 0 )
  65. Sleep( 100 );
  66. bool rel = run;
  67. #ifdef WIN32
  68. #pragma warning(suppress: 6258)
  69. TerminateThread( threadHandle, 0 );
  70. #else
  71. if( pthread_self() == threadHandle )
  72. {
  73. thRegister->addClosedThread( threadHandle );
  74. run = 0;
  75. }
  76. pthread_cancel( threadHandle );
  77. #endif
  78. if( rel )
  79. {
  80. run = 0;
  81. release();
  82. return;
  83. }
  84. }
  85. run = 0;
  86. }
  87. void Thread::thread() // Thread
  88. {}
  89. void Thread::threadEnd()
  90. {
  91. run = 0;
  92. release();
  93. }
  94. // constant
  95. bool Thread::isRunning() const // prüft, ob der Thrad aktiv ist
  96. {
  97. return run;
  98. }
  99. int Thread::warteAufThread( int zeit ) // wartet zeit lang auf den Thread
  100. {
  101. #ifdef WIN32
  102. if( !run )
  103. return WAIT_OBJECT_0;
  104. if( GetCurrentThreadId() == GetThreadId( threadHandle ) )
  105. return WAIT_OBJECT_0;
  106. return WaitForSingleObject( threadHandle, zeit );
  107. #else
  108. if( !run )
  109. return 0;
  110. if( pthread_self() == threadHandle )
  111. return 0;
  112. if( threadHandleSys )
  113. *threadHandleSys = 0;
  114. int ret = pthread_join( threadHandle, 0 );
  115. threadHandle = 0;
  116. return ret;
  117. #endif
  118. }
  119. // Legt einen Frameworkpointer auf ein Threadhandle fest, der auf 0 gesetzt wird, falls die Ressourcen des Threads bereits follstänfig aufgeräumt wurden
  120. // ths: Ein Zeiger auf ein Threadhandle, das verändert werden soll
  121. void Thread::setSystemHandlePointer( pthread_t *ths )
  122. {
  123. threadHandleSys = ths;
  124. *threadHandleSys = threadHandle;
  125. }
  126. pthread_t Thread::getThreadHandle() const
  127. {
  128. return threadHandle;
  129. }
  130. void Thread::addCriticalLock()
  131. {
  132. lockCount++;
  133. }
  134. void Thread::removeCriticalLock()
  135. {
  136. lockCount--;
  137. }
  138. // Erhöht den Reference Counting Zähler.
  139. // return: this.
  140. Thread *Thread::getThis()
  141. {
  142. ref++;
  143. return this;
  144. }
  145. // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
  146. // return: 0.
  147. Thread *Thread::release()
  148. {
  149. if( !--ref )
  150. delete this;
  151. return 0;
  152. }
  153. // funktionen
  154. #ifdef WIN32
  155. unsigned long __stdcall Framework::threadStart( void *param )
  156. {
  157. if( istThreadOk( (Thread *)param ) )
  158. ( (Thread *)param )->thread();
  159. if( istThreadOk( (Thread *)param ) )
  160. ( (Thread *)param )->threadEnd();
  161. return 0;
  162. }
  163. #else
  164. void *Framework::threadStart( void *param )
  165. {
  166. pthread_t handle = 0;
  167. pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, 0 );
  168. if( istThreadOk( (Thread *)param ) )
  169. {
  170. ( (Thread *)param )->setSystemHandlePointer( &handle );
  171. ( (Thread *)param )->thread();
  172. }
  173. if( istThreadOk( (Thread *)param ) )
  174. ( (Thread *)param )->threadEnd();
  175. thRegister->addClosedThread( handle );
  176. pthread_exit( 0 );
  177. return 0;
  178. }
  179. #endif
  180. // Konstruktor
  181. ThreadRegister::ThreadRegister()
  182. {
  183. InitializeCriticalSection( &cs );
  184. }
  185. // Destruktor
  186. ThreadRegister::~ThreadRegister()
  187. {
  188. DeleteCriticalSection( &cs );
  189. }
  190. // Inhalt der ThreadRegister Klasse aus Thread.h
  191. void ThreadRegister::add( Thread *t )
  192. {
  193. EnterCriticalSection( &cs );
  194. threads.add( t );
  195. LeaveCriticalSection( &cs );
  196. }
  197. void ThreadRegister::remove( Thread *t )
  198. {
  199. EnterCriticalSection( &cs );
  200. threads.remove( threads.getWertIndex( t ) );
  201. LeaveCriticalSection( &cs );
  202. }
  203. bool ThreadRegister::isThread( Thread *t )
  204. {
  205. EnterCriticalSection( &cs );
  206. bool ret = threads.hat( threads.getWertIndex( t ) );
  207. LeaveCriticalSection( &cs );
  208. return ret;
  209. }
  210. void ThreadRegister::addClosedThread( pthread_t handle )
  211. {
  212. EnterCriticalSection( &cs );
  213. if( handle )
  214. closedThreads.add( handle );
  215. LeaveCriticalSection( &cs );
  216. }
  217. // Sucht nach einem bestimmten Thread und gibt das zugehörige Objekt zurück
  218. // handle: Ein handle zu dem gesuchten Thread
  219. Thread *ThreadRegister::zThread( pthread_t handle )
  220. {
  221. EnterCriticalSection( &cs );
  222. for( auto i = threads.getIterator(); i; i++ )
  223. {
  224. if( i->getThreadHandle() && GetThreadId( i->getThreadHandle() ) == GetThreadId( handle ) )
  225. {
  226. LeaveCriticalSection( &cs );
  227. return i;
  228. }
  229. }
  230. LeaveCriticalSection( &cs );
  231. return 0;
  232. }
  233. // Löscht die bereits beendetetn Threads und gibt ihre Reccourcen wieder frei
  234. void ThreadRegister::cleanUpClosedThreads()
  235. {
  236. EnterCriticalSection( &cs );
  237. while( closedThreads.getEintragAnzahl() > 0 )
  238. {
  239. #ifndef WIN32
  240. pthread_join( closedThreads.get( 0 ), 0 );
  241. #endif
  242. closedThreads.remove( 0 );
  243. }
  244. LeaveCriticalSection( &cs );
  245. }