Thread.cpp 5.2 KB

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