@@ -187,10 +187,13 @@ REQUIRES(...), REQUIRES_SHARED(...)
187
187
188
188
*Previously *: ``EXCLUSIVE_LOCKS_REQUIRED ``, ``SHARED_LOCKS_REQUIRED ``
189
189
190
- ``REQUIRES `` is an attribute on functions or methods, which
190
+ ``REQUIRES `` is an attribute on functions, methods or function parameters of
191
+ reference to :ref: `scoped_capability `-annotated type, which
191
192
declares that the calling thread must have exclusive access to the given
192
193
capabilities. More than one capability may be specified. The capabilities
193
194
must be held on entry to the function, *and must still be held on exit *.
195
+ Additionally, if the attribute is on a function parameter, it declares that
196
+ the scoped capability manages the specified capabilities in the given order.
194
197
195
198
``REQUIRES_SHARED `` is similar, but requires only shared access.
196
199
@@ -211,17 +214,34 @@ must be held on entry to the function, *and must still be held on exit*.
211
214
mu1.Unlock();
212
215
}
213
216
217
+ void require(MutexLocker& scope REQUIRES(mu1)) {
218
+ scope.Unlock();
219
+ a = 0; // Warning! Requires mu1.
220
+ scope.Lock();
221
+ }
222
+
223
+ void testParameter() {
224
+ MutexLocker scope(&mu1), scope2(&mu2);
225
+ require(scope2); // Warning! Mutex managed by 'scope2' is 'mu2' instead of 'mu1'
226
+ require(scope); // OK.
227
+ scope.Unlock();
228
+ require(scope); // Warning! Requires mu1.
229
+ }
230
+
214
231
215
232
ACQUIRE(...), ACQUIRE_SHARED(...), RELEASE(...), RELEASE_SHARED(...), RELEASE_GENERIC(...)
216
233
------------------------------------------------------------------------------------------
217
234
218
235
*Previously *: ``EXCLUSIVE_LOCK_FUNCTION ``, ``SHARED_LOCK_FUNCTION ``,
219
236
``UNLOCK_FUNCTION ``
220
237
221
- ``ACQUIRE `` and ``ACQUIRE_SHARED `` are attributes on functions or methods
222
- declaring that the function acquires a capability, but does not release it.
238
+ ``ACQUIRE `` and ``ACQUIRE_SHARED `` are attributes on functions, methods
239
+ or function parameters of reference to :ref: `scoped_capability `-annotated type,
240
+ which declare that the function acquires a capability, but does not release it.
223
241
The given capability must not be held on entry, and will be held on exit
224
242
(exclusively for ``ACQUIRE ``, shared for ``ACQUIRE_SHARED ``).
243
+ Additionally, if the attribute is on a function parameter, it declares that
244
+ the scoped capability manages the specified capabilities in the given order.
225
245
226
246
``RELEASE ``, ``RELEASE_SHARED ``, and ``RELEASE_GENERIC `` declare that the
227
247
function releases the given capability. The capability must be held on entry
@@ -249,6 +269,14 @@ shared for ``RELEASE_GENERIC``), and will no longer be held on exit.
249
269
myObject.doSomething(); // Warning, mu is not locked.
250
270
}
251
271
272
+ void release(MutexLocker& scope RELEASE(mu)) {
273
+ } // Warning! Need to unlock mu.
274
+
275
+ void testParameter() {
276
+ MutexLocker scope(&mu);
277
+ release(scope);
278
+ }
279
+
252
280
If no argument is passed to ``ACQUIRE `` or ``RELEASE ``, then the argument is
253
281
assumed to be ``this ``, and the analysis will not check the body of the
254
282
function. This pattern is intended for use by classes which hide locking
@@ -283,10 +311,13 @@ EXCLUDES(...)
283
311
284
312
*Previously *: ``LOCKS_EXCLUDED ``
285
313
286
- ``EXCLUDES `` is an attribute on functions or methods, which declares that
314
+ ``EXCLUDES `` is an attribute on functions, methods or function parameters
315
+ of reference to :ref: `scoped_capability `-annotated type, which declares that
287
316
the caller must *not * hold the given capabilities. This annotation is
288
317
used to prevent deadlock. Many mutex implementations are not re-entrant, so
289
318
deadlock can occur if the function acquires the mutex a second time.
319
+ Additionally, if the attribute is on a function parameter, it declares that
320
+ the scoped capability manages the specified capabilities in the given order.
290
321
291
322
.. code-block :: c++
292
323
@@ -305,6 +336,16 @@ deadlock can occur if the function acquires the mutex a second time.
305
336
mu.Unlock();
306
337
}
307
338
339
+ void exclude(MutexLocker& scope LOCKS_EXCLUDED(mu)) {
340
+ scope.Unlock(); // Warning! mu is not locked.
341
+ scope.Lock();
342
+ } // Warning! mu still held at the end of function.
343
+
344
+ void testParameter() {
345
+ MutexLocker scope(&mu);
346
+ exclude(scope); // Warning, mu is held.
347
+ }
348
+
308
349
Unlike ``REQUIRES ``, ``EXCLUDES `` is optional. The analysis will not issue a
309
350
warning if the attribute is missing, which can lead to false negatives in some
310
351
cases. This issue is discussed further in :ref: `negative `.
@@ -393,6 +434,7 @@ class can be used as a capability. The string argument specifies the kind of
393
434
capability in error messages, e.g. ``"mutex" ``. See the ``Container `` example
394
435
given above, or the ``Mutex `` class in :ref: `mutexheader `.
395
436
437
+ .. _scoped_capability :
396
438
397
439
SCOPED_CAPABILITY
398
440
-----------------
0 commit comments