VirtualBox

source: vbox/trunk/include/iprt/cpp/lock.h@ 69202

Last change on this file since 69202 was 69105, checked in by vboxsync, 7 years ago

include/iprt/: (C) year

  • Property svn:eol-style set to native
File size: 4.0 KB
Line 
1/** @file
2 * IPRT - Classes for Scope-based Locking.
3 */
4
5/*
6 * Copyright (C) 2007-2017 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___iprt_cpp_lock_h
27#define ___iprt_cpp_lock_h
28
29#include <iprt/critsect.h>
30#ifdef RT_LOCK_STRICT
31# include <iprt/lockvalidator.h>
32#endif
33
34RT_C_DECLS_BEGIN
35
36/** @defgroup grp_rt_cpp_lock C++ Scope-based Locking
37 * @ingroup grp_rt_cpp
38 * @{
39 */
40
41class RTCLock;
42
43/**
44 * The mutex lock.
45 *
46 * This is used as an object data member if the intention is to lock
47 * a single object. This can also be used statically, initialized in
48 * a global variable, for class wide purposes.
49 *
50 * This is best used together with RTCLock.
51 */
52class RTCLockMtx
53{
54friend class RTCLock;
55
56private:
57 RTCRITSECT mMtx;
58
59public:
60 RTCLockMtx()
61 {
62#ifdef RT_LOCK_STRICT_ORDER
63 RTCritSectInitEx(&mMtx, 0 /*fFlags*/,
64 RTLockValidatorClassCreateUnique(RT_SRC_POS, NULL),
65 RTLOCKVAL_SUB_CLASS_NONE, NULL);
66#else
67 RTCritSectInit(&mMtx);
68#endif
69 }
70
71 /** Use to when creating locks that belongs in the same "class". */
72 RTCLockMtx(RT_SRC_POS_DECL, uint32_t uSubClass = RTLOCKVAL_SUB_CLASS_NONE)
73 {
74#ifdef RT_LOCK_STRICT_ORDER
75 RTCritSectInitEx(&mMtx, 0 /*fFlags*/,
76 RTLockValidatorClassForSrcPos(RT_SRC_POS_ARGS, NULL),
77 uSubClass, NULL);
78#else
79 NOREF(uSubClass);
80 RTCritSectInit(&mMtx);
81 RT_SRC_POS_NOREF();
82#endif
83 }
84
85 ~RTCLockMtx()
86 {
87 RTCritSectDelete(&mMtx);
88 }
89
90 /* lock() and unlock() are private so that only friend RTCLock can access
91 them. */
92private:
93 inline void lock()
94 {
95 RTCritSectEnter(&mMtx);
96 }
97
98 inline void unlock()
99 {
100 RTCritSectLeave(&mMtx);
101 }
102};
103
104
105/**
106 * The stack object for automatic locking and unlocking.
107 *
108 * This is a helper class for automatic locks, to simplify requesting a
109 * RTCLockMtx and to not forget releasing it. To request a RTCLockMtx, simply
110 * create an instance of RTCLock on the stack and pass the mutex to it:
111 *
112 * @code
113 extern RTCLockMtx gMtx; // wherever this is
114 ...
115 if (...)
116 {
117 RTCLock lock(gMtx);
118 ... // do stuff
119 // when lock goes out of scope, destructor releases the mutex
120 }
121 @endcode
122 *
123 * You can also explicitly release the mutex by calling RTCLock::release().
124 * This might be helpful if the lock doesn't go out of scope early enough
125 * for your mutex to be released.
126 */
127class RTCLock
128{
129private:
130 /** Reference to the lock we're holding. */
131 RTCLockMtx &m_rMtx;
132 /** Whether we're currently holding the lock of if it was already
133 * explictily released by the release() method. */
134 bool m_fLocked;
135
136public:
137 RTCLock(RTCLockMtx &a_rMtx)
138 : m_rMtx(a_rMtx)
139 {
140 m_rMtx.lock();
141 m_fLocked = true;
142 }
143
144 ~RTCLock()
145 {
146 if (m_fLocked)
147 m_rMtx.unlock();
148 }
149
150 inline void release()
151 {
152 if (m_fLocked)
153 {
154 m_rMtx.unlock();
155 m_fLocked = false;
156 }
157 }
158};
159
160
161/** @} */
162
163RT_C_DECLS_END
164
165#endif
166
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette