Thread.cpp 5.1 KB

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