@@ -343,15 +343,19 @@ class SRT_ATTR_CAPABILITY("mutex") Mutex
343343 pthread_mutex_t m_mutex;
344344};
345345
346- // / A pthread version of std::chrono:: scoped_lock<mutex> (or lock_guard for C++11)
346+ // / A pthread version of std::scoped_lock (or lock_guard for C++11).
347347class SRT_ATTR_SCOPED_CAPABILITY ScopedLock
348348{
349349public:
350350 SRT_ATTR_ACQUIRE (m)
351- explicit ScopedLock (Mutex& m);
351+ explicit ScopedLock (Mutex& m)
352+ : m_mutex(m)
353+ {
354+ m_mutex.lock ();
355+ }
352356
353357 SRT_ATTR_RELEASE ()
354- ~ScopedLock ();
358+ ~ScopedLock () { m_mutex. unlock (); }
355359
356360private:
357361 Mutex& m_mutex;
@@ -481,6 +485,122 @@ class Condition
481485inline void setupCond (Condition& cv, const char *) { cv.init (); }
482486inline void releaseCond (Condition& cv) { cv.destroy (); }
483487
488+ // /////////////////////////////////////////////////////////////////////////////
489+ //
490+ // Shared Mutex section
491+ //
492+ // /////////////////////////////////////////////////////////////////////////////
493+
494+ // / Implementation of a read-write mutex.
495+ // / This allows multiple readers at a time, or a single writer.
496+ // / TODO: The class can be improved if needed to give writer a preference
497+ // / by adding additional m_iWritersWaiting member variable (counter).
498+ // / TODO: The m_iCountRead could be made atomic to make unlok_shared() faster and lock-free.
499+ class SharedMutex
500+ {
501+ public:
502+ SharedMutex ();
503+ ~SharedMutex ();
504+
505+ public:
506+ // / Acquire the lock for writting purposes. Only one thread can acquire this lock at a time
507+ // / Once it is locked, no reader can acquire it
508+ void lock ();
509+ bool try_lock ();
510+ void unlock ();
511+
512+ // / Acquire the lock if no writter already has it. For read purpose only
513+ // / Several readers can lock this at the same time.
514+ void lock_shared ();
515+ bool try_lock_shared ();
516+ void unlock_shared ();
517+
518+ int getReaderCount () const ;
519+
520+ protected:
521+ Condition m_LockWriteCond;
522+ Condition m_LockReadCond;
523+
524+ mutable Mutex m_Mutex;
525+
526+ int m_iCountRead;
527+ bool m_bWriterLocked;
528+ };
529+
530+ // / A version of std::scoped_lock<std::shared_mutex> (or lock_guard for C++11).
531+ // / We could have used the srt::sync::ScopedLock making it a template-based class.
532+ // / But in that case all usages would have to be specificed like ScopedLock<Mutex> in C++03.
533+ class SRT_ATTR_SCOPED_CAPABILITY ExclusiveLock
534+ {
535+ public:
536+ SRT_ATTR_ACQUIRE (m)
537+ explicit ExclusiveLock (SharedMutex& m)
538+ : m_mutex(m)
539+ {
540+ m_mutex.lock ();
541+ }
542+
543+ SRT_ATTR_RELEASE ()
544+ ~ExclusiveLock () { m_mutex.unlock (); }
545+
546+ private:
547+ SharedMutex& m_mutex;
548+ };
549+
550+ // / A reduced implementation of the std::shared_lock functionality (available in C++14).
551+ class SRT_ATTR_SCOPED_CAPABILITY SharedLock
552+ {
553+ public:
554+ SRT_ATTR_ACQUIRE_SHARED (m)
555+ explicit SharedLock (SharedMutex& m)
556+ : m_mtx(m)
557+ {
558+ m_mtx.lock_shared ();
559+ }
560+
561+ SRT_ATTR_RELEASE_SHARED (m_mtx)
562+ ~SharedLock () { m_mtx.unlock_shared (); }
563+
564+ private:
565+ SharedMutex& m_mtx;
566+ };
567+
568+ // / A class template for a shared object. It is a wrapper around a pointer to an object
569+ // / and a shared mutex. It allows multiple readers to access the object at the same time,
570+ // / but only one writer can access the object at a time.
571+ template <class T >
572+ class CSharedObjectPtr : public SharedMutex
573+ {
574+ public:
575+ CSharedObjectPtr<T>()
576+ : m_pObj(NULL )
577+ {
578+ }
579+
580+ bool set (T* pObj)
581+ {
582+ ExclusiveLock lock (*this );
583+ if (m_pObj)
584+ return false ;
585+ m_pObj = pObj;
586+ return true ;
587+ }
588+
589+ bool clearIf (const T* pObj)
590+ {
591+ ExclusiveLock lock (*this );
592+ if (m_pObj != pObj)
593+ return false ;
594+ m_pObj = NULL ;
595+ return true ;
596+ }
597+
598+ T* getPtrNoLock () const { return m_pObj; }
599+
600+ private:
601+ T* m_pObj;
602+ };
603+
484604// /////////////////////////////////////////////////////////////////////////////
485605//
486606// Event (CV) section
@@ -943,43 +1063,6 @@ CUDTException& GetThreadLocalError();
9431063// / @param[in] maxVal maximum allowed value of the resulting random number.
9441064int genRandomInt (int minVal, int maxVal);
9451065
946-
947- // / Implementation of a read-write mutex.
948- // / This allows multiple readers at a time, or a single writer.
949- // / TODO: The class can be improved if needed to give writer a preference
950- // / by adding additional m_iWritersWaiting member variable (counter).
951- // / TODO: The m_iCountRead could be made atomic to make unlok_shared() faster and lock-free.
952- class SharedMutex
953- {
954- public:
955- SharedMutex ();
956- ~SharedMutex ();
957-
958- private:
959- Condition m_LockWriteCond;
960- Condition m_LockReadCond;
961-
962- mutable Mutex m_Mutex;
963-
964- int m_iCountRead;
965- bool m_bWriterLocked;
966-
967- // / Acquire the lock for writting purposes. Only one thread can acquire this lock at a time
968- // / Once it is locked, no reader can acquire it
969- public:
970- void lock ();
971- bool try_lock ();
972- void unlock ();
973-
974- // / Acquire the lock if no writter already has it. For read purpose only
975- // / Several readers can lock this at the same time.
976- void lock_shared ();
977- bool try_lock_shared ();
978- void unlock_shared ();
979-
980- int getReaderCount () const ;
981- };
982-
9831066} // namespace sync
9841067} // namespace srt
9851068
0 commit comments