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