Merge pull request #273 from neoflex/webserver-remote-control
[vuplus_xbmc] / xbmc / threads / SharedSection.h
1 #pragma once
2
3 /*
4  *      Copyright (C) 2005-2008 Team XBMC
5  *      http://www.xbmc.org
6  *
7  *  This Program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2, or (at your option)
10  *  any later version.
11  *
12  *  This Program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with XBMC; see the file COPYING.  If not, write to
19  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20  *  http://www.gnu.org/copyleft/gpl.html
21  *
22  */
23
24 #include "threads/Condition.h"
25 #include "threads/SingleLock.h"
26 #include "threads/Helpers.h"
27
28 /**
29  * A CSharedSection is a mutex that satisfies the Shared Lockable concept (see Lockables.h).
30  */
31 class CSharedSection
32 {
33   CCriticalSection sec;
34   XbmcThreads::ConditionVariable actualCv;
35   XbmcThreads::TightConditionVariable<XbmcThreads::InversePredicate<unsigned int&> > cond;
36
37   unsigned int sharedCount;
38
39 public:
40   inline CSharedSection() : cond(actualCv,XbmcThreads::InversePredicate<unsigned int&>(sharedCount)), sharedCount(0)  {}
41
42   inline void lock() { CSingleLock l(sec); if (sharedCount) cond.wait(l); sec.lock(); }
43   inline bool try_lock() { return (sec.try_lock() ? ((sharedCount == 0) ? true : (sec.unlock(), false)) : false); }
44   inline void unlock() { sec.unlock(); }
45
46   inline void lock_shared() { CSingleLock l(sec); sharedCount++; }
47   inline bool try_lock_shared() { return (sec.try_lock() ? sharedCount++, sec.unlock(), true : false); }
48   inline void unlock_shared() { CSingleLock l(sec); sharedCount--; if (!sharedCount) { cond.notifyAll(); } }
49 };
50
51 class CSharedLock : public XbmcThreads::SharedLock<CSharedSection>
52 {
53 public:
54   inline CSharedLock(CSharedSection& cs) : XbmcThreads::SharedLock<CSharedSection>(cs) {}
55   inline CSharedLock(const CSharedSection& cs) : XbmcThreads::SharedLock<CSharedSection>((CSharedSection&)cs) {}
56
57   inline bool IsOwner() const { return owns_lock(); }
58   inline void Enter() { lock(); }
59   inline void Leave() { unlock(); }
60 };
61
62 class CExclusiveLock : public XbmcThreads::UniqueLock<CSharedSection>
63 {
64 public:
65   inline CExclusiveLock(CSharedSection& cs) : XbmcThreads::UniqueLock<CSharedSection>(cs) {}
66   inline CExclusiveLock(const CSharedSection& cs) : XbmcThreads::UniqueLock<CSharedSection> ((CSharedSection&)cs) {}
67
68   inline bool IsOwner() const { return owns_lock(); }
69   inline void Leave() { unlock(); }
70   inline void Enter() { lock(); }
71 };
72