1 /* 2 * Copyright (C) 2005-2018 Team Kodi 3 * This file is part of Kodi - https://kodi.tv 4 * 5 * SPDX-License-Identifier: GPL-2.0-or-later 6 * See LICENSES/README.md for more information. 7 */ 8 9 #pragma once 10 11 #include "threads/Condition.h" 12 #include "threads/Helpers.h" 13 #include "threads/SingleLock.h" 14 15 /** 16 * A CSharedSection is a mutex that satisfies the Shared Lockable concept (see Lockables.h). 17 */ 18 class CSharedSection 19 { 20 CCriticalSection sec; 21 XbmcThreads::ConditionVariable actualCv; 22 XbmcThreads::TightConditionVariable<XbmcThreads::InversePredicate<unsigned int&> > cond; 23 24 unsigned int sharedCount = 0; 25 26 public: CSharedSection()27 inline CSharedSection() : cond(actualCv,XbmcThreads::InversePredicate<unsigned int&>(sharedCount)) {} 28 lock()29 inline void lock() { CSingleLock l(sec); while (sharedCount) cond.wait(l); sec.lock(); } try_lock()30 inline bool try_lock() { return (sec.try_lock() ? ((sharedCount == 0) ? true : (sec.unlock(), false)) : false); } unlock()31 inline void unlock() { sec.unlock(); } 32 lock_shared()33 inline void lock_shared() { CSingleLock l(sec); sharedCount++; } try_lock_shared()34 inline bool try_lock_shared() { return (sec.try_lock() ? sharedCount++, sec.unlock(), true : false); } unlock_shared()35 inline void unlock_shared() { CSingleLock l(sec); sharedCount--; if (!sharedCount) { cond.notifyAll(); } } 36 }; 37 38 class CSharedLock : public XbmcThreads::SharedLock<CSharedSection> 39 { 40 public: CSharedLock(CSharedSection & cs)41 inline explicit CSharedLock(CSharedSection& cs) : XbmcThreads::SharedLock<CSharedSection>(cs) {} 42 IsOwner()43 inline bool IsOwner() const { return owns_lock(); } Enter()44 inline void Enter() { lock(); } Leave()45 inline void Leave() { unlock(); } 46 }; 47 48 class CExclusiveLock : public XbmcThreads::UniqueLock<CSharedSection> 49 { 50 public: CExclusiveLock(CSharedSection & cs)51 inline explicit CExclusiveLock(CSharedSection& cs) : XbmcThreads::UniqueLock<CSharedSection>(cs) {} 52 IsOwner()53 inline bool IsOwner() const { return owns_lock(); } Leave()54 inline void Leave() { unlock(); } Enter()55 inline void Enter() { lock(); } 56 }; 57 58