1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #pragma once
6 #ifdef __cplusplus
7 
8 #include <fbl/macros.h>
9 #include <fbl/mutex.h>
10 #include <fbl/null_lock.h>
11 
12 namespace fbl {
13 
14 // Introduce preprocessor definitions for the underlying mutex data type and the
15 // lock/unlock operations based on whether this code is being used in the kernel
16 // or in user-mode.
17 #ifdef _KERNEL
18 #define fbl_mutex_t mutex_t
19 #define fbl_mutex_acquire mutex_acquire
20 #define fbl_mutex_release mutex_release
21 #else
22 #define fbl_mutex_t mtx_t
23 #define fbl_mutex_acquire mtx_lock
24 #define fbl_mutex_release mtx_unlock
25 #endif
26 
27 class __TA_SCOPED_CAPABILITY AutoLock {
28 public:
AutoLock(fbl_mutex_t * mutex)29     explicit AutoLock(fbl_mutex_t* mutex) __TA_ACQUIRE(mutex)
30         : mutex_(mutex), acquired_(true) {
31         fbl_mutex_acquire(mutex_);
32     }
33 
AutoLock(Mutex * mutex)34     explicit AutoLock(Mutex* mutex) __TA_ACQUIRE(mutex)
35         :   AutoLock(mutex->GetInternal()) {}
36 
AutoLock(fbl::NullLock * mutex)37     explicit AutoLock(fbl::NullLock* mutex) __TA_ACQUIRE(mutex)
38         : mutex_(nullptr), acquired_(false) {}
39 
__TA_RELEASE()40     ~AutoLock()  __TA_RELEASE() {
41         release();
42     }
43 
44     // early release the mutex before the object goes out of scope
release()45     void release() __TA_RELEASE() {
46         // In typical usage, this conditional will be optimized away so
47         // that fbl_mutex_release() is called unconditionally.
48         if (acquired_) {
49             fbl_mutex_release(mutex_);
50             mutex_ = nullptr;
51             acquired_ = false;
52         }
53     }
54 
55     // suppress default constructors
56     DISALLOW_COPY_ASSIGN_AND_MOVE(AutoLock);
57 
58 private:
59     fbl_mutex_t* mutex_;
60     bool acquired_;
61 };
62 
63 }  // namespace fbl
64 
65 // Remove the underlying mutex preprocessor definitions.  Do not let them leak
66 // out into the world at large.
67 #undef fbl_mutex_t
68 #undef fbl_mutex_acquire
69 #undef fbl_mutex_release
70 
71 #endif  // #ifdef __cplusplus
72