VirtualBox

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

Last change on this file was 98103, checked in by vboxsync, 17 months ago

Copyright year updates by scm.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use