123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- #include "Thread.h"
- #include "Globals.h"
- using namespace Framework;
- // inhalt der Thread Klasse aus Thread.h
- // Konstruktor
- Thread::Thread()
- : ReferenceCounter()
- {
- threadHandleSys = 0;
- threadHandle = 0;
- threadId = 0;
- thRegister->add(this);
- run = 0;
- lockCount = 0;
- name = 0;
- }
- // Destruktor
- Thread::~Thread()
- {
- thRegister->remove(this);
- #ifdef WIN32
- if (threadHandle != 0 && GetCurrentThreadId() == GetThreadId(threadHandle))
- return;
- #else
- if (pthread_self() == threadHandle) return;
- #endif
- if (run) warteAufThread(100000);
- if (run) ende();
- }
- // nicht constant
- void Thread::start() // startet den Thread
- {
- if (!run)
- {
- getThis();
- #ifdef WIN32
- threadHandle = CreateThread(0, 0, threadStart, this, 0, &threadId);
- #else
- pthread_create(&threadHandle, NULL, threadStart, this);
- #endif
- }
- run = 1;
- }
- #ifdef WIN32
- void Thread::pause() // pausiert den Thread
- {
- if (run) SuspendThread(threadHandle);
- run = 0;
- }
- void Thread::fortsetzen() // pausiert den Thread
- {
- if (!run) ResumeThread(threadHandle);
- run = 1;
- }
- #endif
- void Thread::ende() // beendet den Thread
- {
- if (run)
- {
- while (lockCount > 0)
- Sleep(100);
- bool rel = run;
- #ifdef WIN32
- # pragma warning(suppress : 6258)
- TerminateThread(threadHandle, 0);
- #else
- if (pthread_self() == threadHandle)
- {
- thRegister->addClosedThread(threadHandle);
- run = 0;
- }
- pthread_cancel(threadHandle);
- #endif
- if (rel)
- {
- run = 0;
- release();
- return;
- }
- }
- run = 0;
- }
- void Thread::thread() // Thread
- {}
- void Thread::threadEnd()
- {
- run = 0;
- release();
- }
- // constant
- bool Thread::isRunning() const // prüft, ob der Thrad aktiv ist
- {
- return run;
- }
- int Thread::warteAufThread(int zeit) // wartet zeit lang auf den Thread
- {
- #ifdef WIN32
- if (!run) return WAIT_OBJECT_0;
- if (GetCurrentThreadId() == GetThreadId(threadHandle)) return WAIT_OBJECT_0;
- return WaitForSingleObject(threadHandle, zeit);
- #else
- if (!run) return 0;
- if (pthread_self() == threadHandle) return 0;
- timespec ts;
- if (clock_gettime(CLOCK_REALTIME, &ts) == -1) return -1;
- ts.tv_sec += (zeit + ts.tv_nsec / 1000) / 1000;
- ts.tv_nsec = 1000 * ((zeit + ts.tv_nsec / 1000) % 1000);
- if (threadHandleSys) *threadHandleSys = 0;
- int ret = pthread_timedjoin_np(threadHandle, 0, &ts);
- if (!ret)
- threadHandle = 0;
- else
- *threadHandleSys = threadHandle;
- return ret;
- #endif
- }
- // Legt einen Frameworkpointer auf ein Threadhandle fest, der auf 0 gesetzt
- // wird, falls die Ressourcen des Threads bereits follstänfig aufgeräumt wurden
- // ths: Ein Zeiger auf ein Threadhandle, das verändert werden soll
- void Thread::setSystemHandlePointer(pthread_t* ths)
- {
- threadHandleSys = ths;
- *threadHandleSys = threadHandle;
- }
- pthread_t Thread::getThreadHandle() const
- {
- return threadHandle;
- }
- // set the name of the thread
- void Thread::setName(const char* name)
- {
- this->name = name;
- }
- // get the name of the thread
- const char* Thread::getName() const
- {
- return name ? name : typeid(*this).name();
- }
- void Thread::addCriticalLock()
- {
- lockCount++;
- }
- void Thread::removeCriticalLock()
- {
- lockCount--;
- }
- // funktionen
- #ifdef WIN32
- unsigned long __stdcall Framework::threadStart(void* param)
- {
- if (istThreadOk((Thread*)param))
- {
- const char* name = ((Thread*)param)->getName();
- wchar_t* wc = new wchar_t[textLength(name) + 1];
- size_t l;
- mbstowcs_s(&l, wc, textLength(name) + 1, name, textLength(name));
- SetThreadDescription(((Thread*)param)->getThreadHandle(), wc);
- delete[] wc;
- ((Thread*)param)->thread();
- }
- if (istThreadOk((Thread*)param)) ((Thread*)param)->threadEnd();
- return 0;
- }
- #else
- void* Framework::threadStart(void* param)
- {
- pthread_t handle = 0;
- pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
- if (istThreadOk((Thread*)param))
- {
- pthread_setname_np(
- ((Thread*)param)->getThreadHandle(), ((Thread*)param)->getName());
- ((Thread*)param)->setSystemHandlePointer(&handle);
- ((Thread*)param)->thread();
- }
- if (istThreadOk((Thread*)param)) ((Thread*)param)->threadEnd();
- thRegister->addClosedThread(handle);
- pthread_exit(0);
- return 0;
- }
- #endif
- // Konstruktor
- ThreadRegister::ThreadRegister()
- {
- InitializeCriticalSection(&cs);
- }
- // Destruktor
- ThreadRegister::~ThreadRegister()
- {
- EnterCriticalSection(&cs);
- while (threads.hat(0))
- {
- LeaveCriticalSection(&cs);
- Sleep(1000); // wait until all threads are done
- EnterCriticalSection(&cs);
- }
- cleanUpClosedThreads();
- LeaveCriticalSection(&cs);
- DeleteCriticalSection(&cs);
- }
- // Inhalt der ThreadRegister Klasse aus Thread.h
- void ThreadRegister::add(Thread* t)
- {
- EnterCriticalSection(&cs);
- threads.add(t);
- LeaveCriticalSection(&cs);
- }
- void ThreadRegister::remove(Thread* t)
- {
- EnterCriticalSection(&cs);
- threads.remove(threads.getWertIndex(t));
- LeaveCriticalSection(&cs);
- }
- bool ThreadRegister::isThread(Thread* t)
- {
- EnterCriticalSection(&cs);
- bool ret = threads.hat(threads.getWertIndex(t));
- LeaveCriticalSection(&cs);
- return ret;
- }
- void ThreadRegister::addClosedThread(pthread_t handle)
- {
- EnterCriticalSection(&cs);
- if (handle) closedThreads.add(handle);
- LeaveCriticalSection(&cs);
- }
- // Sucht nach einem bestimmten Thread und gibt das zugehörige Objekt zurück
- // handle: Ein handle zu dem gesuchten Thread
- Thread* ThreadRegister::zThread(pthread_t handle)
- {
- EnterCriticalSection(&cs);
- for (auto i : threads)
- {
- if (i->getThreadHandle()
- && GetThreadId(i->getThreadHandle()) == GetThreadId(handle)
- && GetThreadId(handle) != 0)
- {
- LeaveCriticalSection(&cs);
- return i;
- }
- }
- LeaveCriticalSection(&cs);
- return 0;
- }
- // sperrt das register
- void ThreadRegister::lock()
- {
- EnterCriticalSection(&cs);
- }
- // entsperrt das register
- void ThreadRegister::unlock()
- {
- LeaveCriticalSection(&cs);
- }
- // Löscht die bereits beendetetn Threads und gibt ihre Reccourcen wieder frei
- void ThreadRegister::cleanUpClosedThreads()
- {
- EnterCriticalSection(&cs);
- while (closedThreads.getEintragAnzahl() > 0)
- {
- #ifndef WIN32
- pthread_join(closedThreads.get(0), 0);
- #endif
- closedThreads.remove(0);
- }
- LeaveCriticalSection(&cs);
- }
|