17fbf6665f96e9272c8c7f0b73b7a6e50636de5b
[libcds.git] / cds / sync / injected_monitor.h
1 //$$CDS-header$$
2
3 #ifndef CDSLIB_SYNC_INJECTED_MONITOR_H
4 #define CDSLIB_SYNC_INJECTED_MONITOR_H
5
6 namespace cds { namespace sync {
7
8     /// @ref cds_sync_monitor "Monitor" that injects the lock into each node
9     /**
10         This monitor injects the lock object of type \p Lock into each node. 
11         The monitor is designed for user-space locking primitives like \ref sync::spin_lock "spin-lock".
12
13         Template arguments:
14         - Lock - lock type like \p std::mutex or \p cds::sync::spin
15
16
17     */
18     template <typename Lock>
19     class injected_monitor
20     {
21     public:
22         typedef Lock lock_type; ///< Lock type
23
24         /// Monitor injection into \p T
25         template <typename T>
26         struct wrapper : public T
27         {
28             using T::T;
29             mutable lock_type m_Lock; ///< Node-level lock
30
31             /// Makes exclusive access to the object
32             void lock() const
33             {
34                 m_Lock.lock;
35             }
36
37             /// Unlocks the object
38             void unlock() const
39             {
40                 m_Lock.unlock();
41             }
42         };
43
44         /// Makes exclusive access to node \p p of type \p T
45         /**
46             \p p must have method \p lock()
47         */
48         template <typename T>
49         void lock( T const& p ) const
50         {
51             p.lock();
52         }
53
54         /// Unlocks the node \p p of type \p T
55         /**
56             \p p must have method \p unlock()
57         */
58         template <typename T>
59         void unlock( T const& p ) const
60         {
61             p.unlock();
62         }
63
64         /// Scoped lock
65         template <typename T>
66         class scoped_lock
67         {
68             T const& m_Locked;  ///< Our locked node
69
70         public:
71             /// Makes exclusive access to object \p p of type T
72             scoped_lock( injected_monitor const&, T const& p )
73                 : m_Locked( p )
74             {
75                 p.lock();
76             }
77
78             /// Unlocks the object
79             ~scoped_lock()
80             {
81                 p.unlock();
82             }
83         };
84     };
85 }} // namespace cds::sync
86
87 #endif // #ifndef CDSLIB_SYNC_INJECTED_MONITOR_H