123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475 |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #include "threading.hpp"
-
- using namespace std;
-
- namespace CodeDweller {
-
- ThreadManager Threads;
-
- void ThreadManager::rememberThread(Thread* T) {
- ScopeMutex ThereCanBeOnlyOne(MyMutex);
- KnownThreads.insert(T);
- }
-
- void ThreadManager::forgetThread(Thread* T) {
- ScopeMutex ThereCanBeOnlyOne(MyMutex);
- KnownThreads.erase(T);
- }
-
- ThreadStatusReport ThreadManager::StatusReport() {
- ScopeMutex ThereCanBeOnlyOne(MyMutex);
- ThreadStatusReport Answer;
- for(
- set<Thread*>::iterator iT = KnownThreads.begin();
- iT != KnownThreads.end(); iT++
- ) {
- Thread& X = *(*iT);
- Answer.push_back(X.StatusReport());
- }
- return Answer;
- }
-
- bool ThreadManager::lockExistingThread(Thread* T) {
- MyMutex.lock();
- if(KnownThreads.end() == KnownThreads.find(T)) {
- MyMutex.unlock();
- return false;
- }
- LockedThread = T;
- return true;
- }
-
- const RuntimeCheck ThreadingCheck1("ThreadManager::unlockExistingThread():ThreadingCheck1(0 != LockedThread)");
- const RuntimeCheck ThreadingCheck2("ThreadManager::unlockExistingThread():ThreadingCheck2(T == LockedThread)");
-
- void ThreadManager::unlockExistingThread(Thread* T) {
- ThreadingCheck1(0 != LockedThread);
- ThreadingCheck2(T == LockedThread);
- LockedThread = 0;
- MyMutex.unlock();
- }
-
-
-
-
-
- ScopeThreadLock::ScopeThreadLock(Thread* T) :
- MyLockedThread(0) {
- if(Threads.lockExistingThread(T)) {
- MyLockedThread = T;
- }
- }
-
- ScopeThreadLock::~ScopeThreadLock() {
- if(0 != MyLockedThread) {
- Threads.unlockExistingThread(MyLockedThread);
- MyLockedThread = 0;
- }
- }
-
- bool ScopeThreadLock::isGood() {
- return (0 != MyLockedThread) ? true:false;
- }
-
- bool ScopeThreadLock::isBad() {
- return (0 == MyLockedThread) ? false:true;
- }
-
-
-
-
- const ThreadType Thread::Type("Generic Thread");
- const ThreadState Thread::ThreadInitialized("Thread Initialized");
- const ThreadState Thread::ThreadStarted("Thread Started");
- const ThreadState Thread::ThreadFailed("Thread Failed");
- const ThreadState Thread::ThreadStopped("Thread Stopped");
- const ThreadState Thread::ThreadDestroyed("Thread Destroyed");
-
- bool Thread::isRunning() { return RunningFlag; }
-
- bool Thread::isBad() { return BadFlag; }
-
- const string Thread::MyFault() { return BadWhat; }
- const string Thread::MyName() { return MyThreadName; }
- const ThreadType& Thread::MyType() { return MyThreadType; }
- const ThreadState& Thread::MyState() { return (*MyThreadState); }
-
- void Thread::CurrentThreadState(const ThreadState& TS) {
- MyThreadState = const_cast<ThreadState*>(&TS);
- }
-
- const ThreadState& Thread::CurrentThreadState() { return (*MyThreadState); }
-
- ThreadStatusRecord Thread::StatusReport() {
- return
- ThreadStatusRecord(
- this,
- const_cast<ThreadType&>(MyThreadType),
- *MyThreadState,
- RunningFlag,
- BadFlag,
- BadWhat,
- MyThreadName
- );
- }
-
-
-
-
- void Thread::launchTask() {
- try {
- RunningFlag = true;
- CurrentThreadState(ThreadStarted);
- myTask();
- }
- catch(exception& e) {
- BadFlag = true;
- BadWhat = e.what();
- }
- catch(...) {
- BadFlag = true;
- BadWhat = "Unkown Exception(...)";
- }
- RunningFlag = false;
- if(BadFlag) CurrentThreadState(ThreadFailed);
- else CurrentThreadState(ThreadStopped);
- }
-
-
-
- thread_primative Thread::getMyThread() { return MyThread; }
-
-
-
-
-
-
-
-
-
-
-
- #ifdef WIN32
-
- Thread::Thread() :
- MyThreadType(Thread::Type),
- MyThreadName("UnNamed Thread"),
- MyThread(NULL),
- RunningFlag(false),
- BadFlag(false) {
- Threads.rememberThread(this);
- CurrentThreadState(ThreadInitialized);
- }
-
- Thread::Thread(const ThreadType& T, const string N) :
- MyThreadType(T),
- MyThreadName(N),
- MyThread(NULL),
- RunningFlag(false),
- BadFlag(false) {
- Threads.rememberThread(this);
- CurrentThreadState(ThreadInitialized);
- }
-
- Thread::~Thread() {
- if(NULL != MyThread) {
- CloseHandle(MyThread);
- }
- RunningFlag = false;
- Threads.forgetThread(this);
- CurrentThreadState(ThreadDestroyed);
- }
-
- unsigned __stdcall runThreadTask(void* thread_object) {
- ((Thread*)thread_object)->launchTask();
- _endthreadex(0);
- return 0;
- }
-
- void Thread::run() {
- unsigned tid;
- MyThread = (HANDLE) _beginthreadex(NULL,0,runThreadTask,this,0,&tid);
- if(NULL == MyThread) BadFlag = true;
- }
-
- void Thread::join() {
- WaitForSingleObject(MyThread, INFINITE);
- }
-
- #else
-
- Thread::Thread() :
- MyThreadType(Thread::Type),
- MyThreadName("UnNamed Thread"),
- RunningFlag(false),
- BadFlag(false) {
- Threads.rememberThread(this);
- CurrentThreadState(ThreadInitialized);
- }
-
- Thread::Thread(const ThreadType& T, const string N) :
- MyThreadType(T),
- MyThreadName(N),
- RunningFlag(false),
- BadFlag(false) {
- Threads.rememberThread(this);
- CurrentThreadState(ThreadInitialized);
- }
-
- Thread::~Thread() {
- RunningFlag = false;
- Threads.forgetThread(this);
- CurrentThreadState(ThreadDestroyed);
- }
-
- void* runThreadTask(void* thread_object) {
- ((Thread*)thread_object)->launchTask();
- return NULL;
- }
-
- void Thread::run() {
- int result = pthread_create(&MyThread, NULL, runThreadTask, this);
- if(0 != result) BadFlag = true;
- }
-
- void Thread::join() {
- pthread_join(MyThread, NULL);
- }
-
- #endif
-
-
-
-
-
-
-
- #ifdef WIN32
-
-
-
-
-
-
-
-
- const RuntimeCheck ThreadingCheck3("Mutex::Mutex():ThreadingCheck3(NULL != MyMutex)");
-
- Mutex::Mutex() :
- IAmLocked(false) {
- MyMutex = CreateSemaphore(NULL, 1, 1, NULL);
- ThreadingCheck3(NULL != MyMutex);
- }
-
- const ExitCheck ThreadingCheck4("Mutex::~Mutex():");
-
- Mutex::~Mutex() {
- ThreadingCheck4(false == IAmLocked);
- CloseHandle(MyMutex);
- }
-
- bool Mutex::tryLock() {
- bool DoIHaveIt = false;
- if(
- false == IAmLocked &&
- WAIT_OBJECT_0 == WaitForSingleObject(MyMutex, 0)
- ) {
- IAmLocked = true;
- DoIHaveIt = true;
- }
- return DoIHaveIt;
- }
-
- const RuntimeCheck ThreadingCheck5("Mutex::lock():ThreadingCheck5(WAIT_OBJECT_0 == WaitForSingleObject(MyMutex, INFINITE))");
-
- void Mutex::lock() {
- ThreadingCheck5(WAIT_OBJECT_0 == WaitForSingleObject(MyMutex, INFINITE));
- IAmLocked = true;
- }
-
- const LogicCheck ThreadingCheck6("Mutex::unlock():ThreadingCheck6(true == IAmLocked)");
-
- void Mutex::unlock() {
- ThreadingCheck6(true == IAmLocked);
- IAmLocked = false;
- ReleaseSemaphore(MyMutex, 1, NULL);
- }
-
- bool Mutex::isLocked() { return IAmLocked; }
-
- #else
-
-
-
- const RuntimeCheck ThreadingCheck7("Mutex::Mutex():ThreadingCheck7(0 == pthread_mutex_init(&MyMutex,NULL))");
-
- Mutex::Mutex() :
- IAmLocked(false) {
- ThreadingCheck7(0 == pthread_mutex_init(&MyMutex,NULL));
- }
-
- const ExitCheck ThreadingCheck8("Mutex::~Mutex():ThreadingCheck8(false == IAmLocked)");
- const ExitCheck ThreadingCheck9("Mutex::~Mutex():ThreadingCheck9(0 == pthread_mutex_destroy(&MyMutex))");
-
- Mutex::~Mutex() {
- ThreadingCheck8(false == IAmLocked);
- ThreadingCheck9(0 == pthread_mutex_destroy(&MyMutex));
- }
-
- const RuntimeCheck ThreadingCheck10("Mutex::lock():ThreadingCheck10(0 == pthread_mutex_lock(&MyMutex));");
-
- void Mutex::lock() {
- ThreadingCheck10(0 == pthread_mutex_lock(&MyMutex));
- IAmLocked = true;
- }
-
- const LogicCheck ThreadingCheck11("Mutex::unlock():ThreadingCheck11(true == IAmLocked)");
- const RuntimeCheck ThreadingCheck12("Mutex::unlock():ThreadingCheck12(0 == pthread_mutex_unlock(&MyMutex))");
-
- void Mutex::unlock() {
- ThreadingCheck11(true == IAmLocked);
- IAmLocked = false;
- ThreadingCheck12(0 == pthread_mutex_unlock(&MyMutex));
- }
-
- bool Mutex::tryLock() {
- bool DoIHaveIt = false;
- if(false == IAmLocked) {
- if(0 == pthread_mutex_trylock(&MyMutex)) {
- IAmLocked = true;
- DoIHaveIt = true;
- }
- }
- return DoIHaveIt;
- }
-
- bool Mutex::isLocked() { return IAmLocked; }
-
- #endif
-
-
-
-
-
-
-
- ScopeMutex::ScopeMutex(Mutex& M) :
- MyMutex(M) {
- MyMutex.lock();
- }
-
- ScopeMutex::~ScopeMutex() {
- MyMutex.unlock();
- }
-
-
-
-
-
-
-
- #ifdef WIN32
-
-
-
- const RuntimeCheck ThreadingCheck13("ProductionGateway::ProductionGateway():ThreadingCheck13(NULL != MySemaphore)");
-
- ProductionGateway::ProductionGateway() {
- const int HUGENUMBER = 0x7fffffL;
- MySemaphore = CreateSemaphore(NULL, 0, HUGENUMBER, NULL);
- ThreadingCheck13(NULL != MySemaphore);
- }
-
- ProductionGateway::~ProductionGateway() {
- CloseHandle(MySemaphore);
- }
-
- void ProductionGateway::produce() {
- ReleaseSemaphore(MySemaphore, 1, NULL);
- }
-
- void ProductionGateway::consume() {
- WaitForSingleObject(MySemaphore, INFINITE);
- }
-
- #else
-
-
-
- const RuntimeCheck ThreadingCheck14("ProductionGateway::ProductionGateway():ThreadingCheck14(0 == pthread_mutex_init(&MyMutex, NULL));");
- const RuntimeCheck ThreadingCheck15("ProductionGateway::ProductionGateway():ThreadingCheck15(0 == pthread_cond_init(&MyConditionVariable, NULL))");
-
- ProductionGateway::ProductionGateway() :
- Product(0),
- Waiting(0),
- Signaled(0) {
- ThreadingCheck14(0 == pthread_mutex_init(&MyMutex, NULL));
- ThreadingCheck15(0 == pthread_cond_init(&MyConditionVariable, NULL));
- }
-
- const ExitCheck ThreadingCheck16("ProductionGateway::~ProductionGateway():ThreadingCheck16(0 == pthread_mutex_destroy(&MyMutex))");
- const ExitCheck ThreadingCheck17("ProductionGateway::~ProductionGateway():ThreadingCheck17(0 == pthread_cond_destroy(&MyConditionVariable))");
-
- ProductionGateway::~ProductionGateway() {
- ThreadingCheck16(0 == pthread_mutex_destroy(&MyMutex));
- ThreadingCheck17(0 == pthread_cond_destroy(&MyConditionVariable));
- }
-
- const RuntimeCheck ThreadingCheck18("ProductionGateway::produce():ThreadingCheck18(0 == pthread_mutex_lock(&MyMutex))");
- const RuntimeCheck ThreadingCheck19("ProductionGateway::produce():ThreadingCheck19(0 == pthread_cond_signal(&MyConditionVariable))");
- const RuntimeCheck ThreadingCheck20("ProductionGateway::produce():ThreadingCheck20(0 == pthread_mutex_unlock(&MyMutex))");
-
- void ProductionGateway::produce() {
- ThreadingCheck18(0 == pthread_mutex_lock(&MyMutex));
- ++Product;
- if(Signaled < Waiting) {
- ThreadingCheck19(0 == pthread_cond_signal(&MyConditionVariable));
- ++Signaled;
- }
- ThreadingCheck20(0 == pthread_mutex_unlock(&MyMutex));
- }
-
- const RuntimeCheck ThreadingCheck21("ProductionGateway::consume():ThreadingCheck21(0 == pthread_mutex_lock(&MyMutex))");
- const RuntimeCheck ThreadingCheck22("ProductionGateway::consume():ThreadingCheck22(0 == pthread_cond_wait(&MyConditionVariable, &MyMutex))");
- const RuntimeCheck ThreadingCheck23("ProductionGateway::consume():ThreadingCheck23(0 == pthread_mutex_unlock(&MyMutex))");
-
- void ProductionGateway::consume() {
- ThreadingCheck21(0 == pthread_mutex_lock(&MyMutex));
- while(0 >= Product) {
- ++Waiting;
- ThreadingCheck22(0 == pthread_cond_wait(&MyConditionVariable, &MyMutex));
- --Waiting;
- --Signaled;
- }
- --Product;
- ThreadingCheck23(0 == pthread_mutex_unlock(&MyMutex));
- }
-
- #endif
-
-
-
- }
|