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