#pragma once ///////////////////////////////////////////////////////////////////// // Locks.h - defines a locking class and a nolocking class // // // // Jim Fawcett, CSE776 - Design Patterns, Fall 2017 // ///////////////////////////////////////////////////////////////////// /* * - Needs to use a recursive lock if a thread might attempt to * acquire a thread it already owns. That is the case in some * of the code in this solution. * - lock is acquired when constructed and released when it goes out * of scope. */ #include "../Utilities/Utilities.h" #include #include namespace Locks { Utilities::Log log; struct NoLocking { void Lock() {} ~NoLocking() {} }; class Locking { public: Locking() : lock_(mtx) // constructs std::lock_guard with shared mutex { bool save = log.logging; log.logging = false; log.doLog( "\n lock acquired on thread " + Utilities::toString(std::this_thread::get_id()) ); log.logging = save; } ~Locking() { bool save = log.logging; log.logging = false; log.doLog( "\n lock released " + Utilities::toString(std::this_thread::get_id()) ); log.logging = save; } private: static std::recursive_mutex mtx; std::lock_guard lock_; // released when object goes out of scope }; std::recursive_mutex Locking::mtx; }