Thread.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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. : ReferenceCounter()
  8. {
  9. threadHandleSys = 0;
  10. threadHandle = 0;
  11. threadId = 0;
  12. thRegister->add( this );
  13. run = 0;
  14. lockCount = 0;
  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. getThis();
  38. #ifdef WIN32
  39. threadHandle = CreateThread( 0, 0, threadStart, this, 0, &threadId );
  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. // funktionen
  139. #ifdef WIN32
  140. unsigned long __stdcall Framework::threadStart( void *param )
  141. {
  142. if( istThreadOk( (Thread *)param ) )
  143. ( (Thread *)param )->thread();
  144. if( istThreadOk( (Thread *)param ) )
  145. ( (Thread *)param )->threadEnd();
  146. return 0;
  147. }
  148. #else
  149. void *Framework::threadStart( void *param )
  150. {
  151. pthread_t handle = 0;
  152. pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, 0 );
  153. if( istThreadOk( (Thread *)param ) )
  154. {
  155. ( (Thread *)param )->setSystemHandlePointer( &handle );
  156. ( (Thread *)param )->thread();
  157. }
  158. if( istThreadOk( (Thread *)param ) )
  159. ( (Thread *)param )->threadEnd();
  160. thRegister->addClosedThread( handle );
  161. pthread_exit( 0 );
  162. return 0;
  163. }
  164. #endif
  165. // Konstruktor
  166. ThreadRegister::ThreadRegister()
  167. {
  168. InitializeCriticalSection( &cs );
  169. }
  170. // Destruktor
  171. ThreadRegister::~ThreadRegister()
  172. {
  173. DeleteCriticalSection( &cs );
  174. }
  175. // Inhalt der ThreadRegister Klasse aus Thread.h
  176. void ThreadRegister::add( Thread *t )
  177. {
  178. EnterCriticalSection( &cs );
  179. threads.add( t );
  180. LeaveCriticalSection( &cs );
  181. }
  182. void ThreadRegister::remove( Thread *t )
  183. {
  184. EnterCriticalSection( &cs );
  185. threads.remove( threads.getWertIndex( t ) );
  186. LeaveCriticalSection( &cs );
  187. }
  188. bool ThreadRegister::isThread( Thread *t )
  189. {
  190. EnterCriticalSection( &cs );
  191. bool ret = threads.hat( threads.getWertIndex( t ) );
  192. LeaveCriticalSection( &cs );
  193. return ret;
  194. }
  195. void ThreadRegister::addClosedThread( pthread_t handle )
  196. {
  197. EnterCriticalSection( &cs );
  198. if( handle )
  199. closedThreads.add( handle );
  200. LeaveCriticalSection( &cs );
  201. }
  202. // Sucht nach einem bestimmten Thread und gibt das zugehörige Objekt zurück
  203. // handle: Ein handle zu dem gesuchten Thread
  204. Thread *ThreadRegister::zThread( pthread_t handle )
  205. {
  206. EnterCriticalSection( &cs );
  207. for( auto i = threads.getIterator(); i; i++ )
  208. {
  209. if( i->getThreadHandle() && GetThreadId( i->getThreadHandle() ) == GetThreadId( handle ) && GetThreadId( handle ) != 0 )
  210. {
  211. LeaveCriticalSection( &cs );
  212. return i;
  213. }
  214. }
  215. LeaveCriticalSection( &cs );
  216. return 0;
  217. }
  218. // sperrt das register
  219. void ThreadRegister::lock()
  220. {
  221. EnterCriticalSection( &cs );
  222. }
  223. // entsperrt das register
  224. void ThreadRegister::unlock()
  225. {
  226. LeaveCriticalSection( &cs );
  227. }
  228. // Löscht die bereits beendetetn Threads und gibt ihre Reccourcen wieder frei
  229. void ThreadRegister::cleanUpClosedThreads()
  230. {
  231. EnterCriticalSection( &cs );
  232. while( closedThreads.getEintragAnzahl() > 0 )
  233. {
  234. #ifndef WIN32
  235. pthread_join( closedThreads.get( 0 ), 0 );
  236. #endif
  237. closedThreads.remove( 0 );
  238. }
  239. LeaveCriticalSection( &cs );
  240. }