// Copyright (C) 2005 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #ifndef DLIB_RMUTEX_EXTENSIOn_ #define DLIB_RMUTEX_EXTENSIOn_ #include "threads_kernel.h" #include "rmutex_extension_abstract.h" namespace dlib { // ---------------------------------------------------------------------------------------- class rmutex { /*! INITIAL VALUE count == 0 thread_id == 0 CONVENTION - count == lock_count() - if (no thread currently has a lock on this mutex) then - count == 0 - else - count == the number of times the thread that owns this mutex has called lock() - thread_id == the id of this thread. !*/ public: rmutex ( ) : s(m), thread_id(0), count(0) {} ~rmutex ( ) {} unsigned long lock_count ( ) const { return count; } void lock ( unsigned long times = 1 ) const { const thread_id_type current_thread_id = get_thread_id(); m.lock(); if (thread_id == current_thread_id) { // we already own this mutex in this case count += times; } else { // wait for our turn to claim this rmutex while (count != 0) s.wait(); count = times; thread_id = current_thread_id; } m.unlock(); } void unlock ( unsigned long times = 1 ) const { const thread_id_type current_thread_id = get_thread_id(); m.lock(); if (thread_id == current_thread_id) { if (count <= times) { count = 0; s.signal(); } else { count -= times; } } m.unlock(); } private: mutex m; signaler s; mutable thread_id_type thread_id; mutable unsigned long count; // restricted functions rmutex(rmutex&); // copy constructor rmutex& operator=(rmutex&); // assignment operator }; // ---------------------------------------------------------------------------------------- } #endif // DLIB_RMUTEX_EXTENSIOn_