13b78f2531a944fee7e8127e3976c9e4312a735e
[libcds.git] / cds / lock / scoped_lock.h
1 //$$CDS-header$$-2
2
3 #ifndef __CDS_LOCK_SCOPED_LOCK_H
4 #define __CDS_LOCK_SCOPED_LOCK_H
5
6 #include <cds/details/defs.h>
7 #include <cds/details/noncopyable.h>
8
9 namespace cds { namespace lock {
10
11     /// Scoped lock
12     /**
13
14         An object of type \p scoped_lock controls the ownership of a lockable object within a scope.
15         A \p scoped_lock object maintains ownership of a lockable object throughout the \p scoped_lock object\92s lifetime.
16         The behavior of a program is undefined if the lockable object does not exist for the entire lifetime
17         of the \p scoped_lock object.
18         The supplied \p Lock type shall have two methods: \p lock and \p unlock.
19
20         The constructor locks the wrapped lock object, the destructor unlocks it.
21
22         Scoped lock is not copy-constructible and not default-constructible.
23
24         This class is similar to \p std::lock_quard
25     */
26     template <class Lock>
27     class scoped_lock: public cds::details::noncopyable
28     {
29     public:
30         typedef Lock lock_type ;    ///< Lock type
31
32     protected:
33         lock_type&  m_Lock ;        ///< Owned lock object
34
35     protected:
36         //@cond
37         // Only for internal use!!!
38         scoped_lock()
39         {}
40         //@endcond
41     public:
42         /// Get ownership of lock object \p l and calls <tt>l.lock()</tt>
43         scoped_lock( lock_type& l )
44             : m_Lock( l )
45         {
46             l.lock();
47         }
48
49         /// Get ownership of lock object \p l and conditionally locks it
50         /**
51             The constructor calls <tt>l.lock()</tt> only if \p bAlreadyLocked is \p false.
52             If \p bAlreadyLocked is \p true, no locking is performed.
53
54             In any case, the destructor of \p scoped_lock object invokes <tt>l.unlock()</tt>.
55         */
56         scoped_lock( lock_type& l, bool bAlreadyLocked )
57             : m_Lock( l )
58         {
59             if ( !bAlreadyLocked )
60                 l.lock();
61         }
62
63         /// Unlock underlying lock object and release ownership
64         ~scoped_lock()
65         {
66             m_Lock.unlock();
67         }
68     };
69 }}  // namespace cds::lock
70
71
72 #endif // #ifndef __CDS_LOCK_SCOPED_LOCK_H