| #include "threading.hpp" | #include "threading.hpp" | ||||
| using namespace std; // Introduce std namespace. | |||||
| namespace cd = codedweller; | |||||
| ThreadManager Threads; // Master thread manager. | ThreadManager Threads; // Master thread manager. | ||||
| return true; // return true; | return true; // return true; | ||||
| } | } | ||||
| const RuntimeCheck ThreadingCheck1("ThreadManager::unlockExistingThread():ThreadingCheck1(0 != LockedThread)"); | |||||
| const RuntimeCheck ThreadingCheck2("ThreadManager::unlockExistingThread():ThreadingCheck2(T == LockedThread)"); | |||||
| const cd::RuntimeCheck ThreadingCheck1("ThreadManager::unlockExistingThread():ThreadingCheck1(0 != LockedThread)"); | |||||
| const cd::RuntimeCheck ThreadingCheck2("ThreadManager::unlockExistingThread():ThreadingCheck2(T == LockedThread)"); | |||||
| void ThreadManager::unlockExistingThread(Thread* T) { // Unlocks ThreadManager if T locked. | void ThreadManager::unlockExistingThread(Thread* T) { // Unlocks ThreadManager if T locked. | ||||
| ThreadingCheck1(0 != LockedThread); // We had better have a locked thread. | ThreadingCheck1(0 != LockedThread); // We had better have a locked thread. | ||||
| // POSIX Mutex Implementation ////////////////////////////////////////////////// | // POSIX Mutex Implementation ////////////////////////////////////////////////// | ||||
| const RuntimeCheck ThreadingCheck7("Mutex::Mutex():ThreadingCheck7(0 == pthread_mutex_init(&MyMutex,NULL))"); | |||||
| const cd::RuntimeCheck ThreadingCheck7("Mutex::Mutex():ThreadingCheck7(0 == pthread_mutex_init(&MyMutex,NULL))"); | |||||
| Mutex::Mutex() : // Constructing a POSIX mutex means | Mutex::Mutex() : // Constructing a POSIX mutex means | ||||
| IAmLocked(false) { // setting the IAmLocked flag to false and | IAmLocked(false) { // setting the IAmLocked flag to false and | ||||
| ThreadingCheck7(0 == pthread_mutex_init(&MyMutex,NULL)); // initializing the mutex_t object. | ThreadingCheck7(0 == pthread_mutex_init(&MyMutex,NULL)); // initializing the mutex_t object. | ||||
| } | } | ||||
| const ExitCheck ThreadingCheck8("Mutex::~Mutex():ThreadingCheck8(false == IAmLocked)"); | |||||
| const ExitCheck ThreadingCheck9("Mutex::~Mutex():ThreadingCheck9(0 == pthread_mutex_destroy(&MyMutex))"); | |||||
| const cd::ExitCheck ThreadingCheck8("Mutex::~Mutex():ThreadingCheck8(false == IAmLocked)"); | |||||
| const cd::ExitCheck ThreadingCheck9("Mutex::~Mutex():ThreadingCheck9(0 == pthread_mutex_destroy(&MyMutex))"); | |||||
| Mutex::~Mutex() { // Before we destroy our mutex we check | Mutex::~Mutex() { // Before we destroy our mutex we check | ||||
| ThreadingCheck8(false == IAmLocked); // to see that it is not locked and | ThreadingCheck8(false == IAmLocked); // to see that it is not locked and | ||||
| ThreadingCheck9(0 == pthread_mutex_destroy(&MyMutex)); // destroy the primative. | ThreadingCheck9(0 == pthread_mutex_destroy(&MyMutex)); // destroy the primative. | ||||
| } | } | ||||
| const RuntimeCheck ThreadingCheck10("Mutex::lock():ThreadingCheck10(0 == pthread_mutex_lock(&MyMutex));"); | |||||
| const cd::RuntimeCheck ThreadingCheck10("Mutex::lock():ThreadingCheck10(0 == pthread_mutex_lock(&MyMutex));"); | |||||
| void Mutex::lock() { // Locking a POSIX mutex means | void Mutex::lock() { // Locking a POSIX mutex means | ||||
| ThreadingCheck10(0 == pthread_mutex_lock(&MyMutex)); // asserting our lock was successful and | ThreadingCheck10(0 == pthread_mutex_lock(&MyMutex)); // asserting our lock was successful and | ||||
| IAmLocked = true; // setting the IAmLocked flag. | IAmLocked = true; // setting the IAmLocked flag. | ||||
| } | } | ||||
| const LogicCheck ThreadingCheck11("Mutex::unlock():ThreadingCheck11(true == IAmLocked)"); | |||||
| const RuntimeCheck ThreadingCheck12("Mutex::unlock():ThreadingCheck12(0 == pthread_mutex_unlock(&MyMutex))"); | |||||
| const cd::LogicCheck ThreadingCheck11("Mutex::unlock():ThreadingCheck11(true == IAmLocked)"); | |||||
| const cd::RuntimeCheck ThreadingCheck12("Mutex::unlock():ThreadingCheck12(0 == pthread_mutex_unlock(&MyMutex))"); | |||||
| void Mutex::unlock() { // Unlocking a POSIX mutex means | void Mutex::unlock() { // Unlocking a POSIX mutex means | ||||
| ThreadingCheck11(true == IAmLocked); // asserting that we are locked, | ThreadingCheck11(true == IAmLocked); // asserting that we are locked, | ||||
| // POSIX Implementation //////////////////////////////////////////////////////// | // POSIX Implementation //////////////////////////////////////////////////////// | ||||
| const RuntimeCheck ThreadingCheck14("ProductionGateway::ProductionGateway():ThreadingCheck14(0 == pthread_mutex_init(&MyMutex, NULL));"); | |||||
| const RuntimeCheck ThreadingCheck15("ProductionGateway::ProductionGateway():ThreadingCheck15(0 == pthread_cond_init(&MyConditionVariable, NULL))"); | |||||
| const cd::RuntimeCheck ThreadingCheck14("ProductionGateway::ProductionGateway():ThreadingCheck14(0 == pthread_mutex_init(&MyMutex, NULL));"); | |||||
| const cd::RuntimeCheck ThreadingCheck15("ProductionGateway::ProductionGateway():ThreadingCheck15(0 == pthread_cond_init(&MyConditionVariable, NULL))"); | |||||
| ProductionGateway::ProductionGateway() : // Construct in POSIX like this: | ProductionGateway::ProductionGateway() : // Construct in POSIX like this: | ||||
| Product(0), // All of our counts start at zero. | Product(0), // All of our counts start at zero. | ||||
| ThreadingCheck15(0 == pthread_cond_init(&MyConditionVariable, NULL)); // Initialize our condition variable. | ThreadingCheck15(0 == pthread_cond_init(&MyConditionVariable, NULL)); // Initialize our condition variable. | ||||
| } | } | ||||
| const ExitCheck ThreadingCheck16("ProductionGateway::~ProductionGateway():ThreadingCheck16(0 == pthread_mutex_destroy(&MyMutex))"); | |||||
| const ExitCheck ThreadingCheck17("ProductionGateway::~ProductionGateway():ThreadingCheck17(0 == pthread_cond_destroy(&MyConditionVariable))"); | |||||
| const cd::ExitCheck ThreadingCheck16("ProductionGateway::~ProductionGateway():ThreadingCheck16(0 == pthread_mutex_destroy(&MyMutex))"); | |||||
| const cd::ExitCheck ThreadingCheck17("ProductionGateway::~ProductionGateway():ThreadingCheck17(0 == pthread_cond_destroy(&MyConditionVariable))"); | |||||
| ProductionGateway::~ProductionGateway() { // When we're done we must destroy | ProductionGateway::~ProductionGateway() { // When we're done we must destroy | ||||
| ThreadingCheck16(0 == pthread_mutex_destroy(&MyMutex)); // our local mutex and | ThreadingCheck16(0 == pthread_mutex_destroy(&MyMutex)); // our local mutex and | ||||
| ThreadingCheck17(0 == pthread_cond_destroy(&MyConditionVariable)); // our condition variable. | ThreadingCheck17(0 == pthread_cond_destroy(&MyConditionVariable)); // our condition variable. | ||||
| } | } | ||||
| 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))"); | |||||
| const cd::RuntimeCheck ThreadingCheck18("ProductionGateway::produce():ThreadingCheck18(0 == pthread_mutex_lock(&MyMutex))"); | |||||
| const cd::RuntimeCheck ThreadingCheck19("ProductionGateway::produce():ThreadingCheck19(0 == pthread_cond_signal(&MyConditionVariable))"); | |||||
| const cd::RuntimeCheck ThreadingCheck20("ProductionGateway::produce():ThreadingCheck20(0 == pthread_mutex_unlock(&MyMutex))"); | |||||
| void ProductionGateway::produce() { // To produce in POSIX | void ProductionGateway::produce() { // To produce in POSIX | ||||
| ThreadingCheck18(0 == pthread_mutex_lock(&MyMutex)); // Lock our mutex. | ThreadingCheck18(0 == pthread_mutex_lock(&MyMutex)); // Lock our mutex. | ||||
| ThreadingCheck20(0 == pthread_mutex_unlock(&MyMutex)); // At the end unlock our mutex so | ThreadingCheck20(0 == pthread_mutex_unlock(&MyMutex)); // At the end unlock our mutex so | ||||
| } // waiting threads can fly free :-) | } // waiting threads can fly free :-) | ||||
| 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))"); | |||||
| const cd::RuntimeCheck ThreadingCheck21("ProductionGateway::consume():ThreadingCheck21(0 == pthread_mutex_lock(&MyMutex))"); | |||||
| const cd::RuntimeCheck ThreadingCheck22("ProductionGateway::consume():ThreadingCheck22(0 == pthread_cond_wait(&MyConditionVariable, &MyMutex))"); | |||||
| const cd::RuntimeCheck ThreadingCheck23("ProductionGateway::consume():ThreadingCheck23(0 == pthread_mutex_unlock(&MyMutex))"); | |||||
| void ProductionGateway::consume() { // To consume in POSIX | void ProductionGateway::consume() { // To consume in POSIX | ||||
| ThreadingCheck21(0 == pthread_mutex_lock(&MyMutex)); // Lock our mutex. | ThreadingCheck21(0 == pthread_mutex_lock(&MyMutex)); // Lock our mutex. |