File indexing completed on 2025-07-30 08:46:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef __TBB_detail_scoped_lock_H
0018 #define __TBB_detail_scoped_lock_H
0019
0020 namespace tbb {
0021 namespace detail {
0022 namespace d1 {
0023
0024
0025 template <typename Mutex>
0026 class unique_scoped_lock {
0027
0028 Mutex* m_mutex{};
0029
0030 public:
0031
0032 constexpr unique_scoped_lock() noexcept : m_mutex(nullptr) {}
0033
0034
0035 unique_scoped_lock(Mutex& m) {
0036 acquire(m);
0037 }
0038
0039
0040 unique_scoped_lock(const unique_scoped_lock&) = delete;
0041 unique_scoped_lock& operator=(const unique_scoped_lock&) = delete;
0042
0043
0044 void acquire(Mutex& m) {
0045 __TBB_ASSERT(m_mutex == nullptr, "The mutex is already acquired");
0046 m_mutex = &m;
0047 m.lock();
0048 }
0049
0050
0051
0052 bool try_acquire(Mutex& m) {
0053 __TBB_ASSERT(m_mutex == nullptr, "The mutex is already acquired");
0054 bool succeed = m.try_lock();
0055 if (succeed) {
0056 m_mutex = &m;
0057 }
0058 return succeed;
0059 }
0060
0061
0062 void release() {
0063 __TBB_ASSERT(m_mutex, "release on Mutex::unique_scoped_lock that is not holding a lock");
0064 m_mutex->unlock();
0065 m_mutex = nullptr;
0066 }
0067
0068
0069 ~unique_scoped_lock() {
0070 if (m_mutex) {
0071 release();
0072 }
0073 }
0074 };
0075
0076
0077 template <typename Mutex>
0078 class rw_scoped_lock {
0079 public:
0080
0081
0082 constexpr rw_scoped_lock() noexcept {}
0083
0084
0085 rw_scoped_lock(Mutex& m, bool write = true) {
0086 acquire(m, write);
0087 }
0088
0089
0090 ~rw_scoped_lock() {
0091 if (m_mutex) {
0092 release();
0093 }
0094 }
0095
0096
0097 rw_scoped_lock(const rw_scoped_lock&) = delete;
0098 rw_scoped_lock& operator=(const rw_scoped_lock&) = delete;
0099
0100
0101 void acquire(Mutex& m, bool write = true) {
0102 __TBB_ASSERT(m_mutex == nullptr, "The mutex is already acquired");
0103 m_is_writer = write;
0104 m_mutex = &m;
0105 if (write) {
0106 m_mutex->lock();
0107 } else {
0108 m_mutex->lock_shared();
0109 }
0110 }
0111
0112
0113 bool try_acquire(Mutex& m, bool write = true) {
0114 bool succeed = write ? m.try_lock() : m.try_lock_shared();
0115 if (succeed) {
0116 m_mutex = &m;
0117 m_is_writer = write;
0118 }
0119 return succeed;
0120 }
0121
0122
0123 void release() {
0124 __TBB_ASSERT(m_mutex != nullptr, "The mutex is not acquired");
0125 Mutex* m = m_mutex;
0126 m_mutex = nullptr;
0127
0128 if (m_is_writer) {
0129 m->unlock();
0130 } else {
0131 m->unlock_shared();
0132 }
0133 }
0134
0135
0136
0137 bool upgrade_to_writer() {
0138 __TBB_ASSERT(m_mutex != nullptr, "The mutex is not acquired");
0139 if (m_is_writer) {
0140 return true;
0141 }
0142 m_is_writer = true;
0143 return m_mutex->upgrade();
0144 }
0145
0146
0147 bool downgrade_to_reader() {
0148 __TBB_ASSERT(m_mutex != nullptr, "The mutex is not acquired");
0149 if (m_is_writer) {
0150 m_mutex->downgrade();
0151 m_is_writer = false;
0152 }
0153 return true;
0154 }
0155
0156 bool is_writer() const {
0157 __TBB_ASSERT(m_mutex != nullptr, "The mutex is not acquired");
0158 return m_is_writer;
0159 }
0160
0161 protected:
0162
0163 Mutex* m_mutex {nullptr};
0164
0165
0166
0167 bool m_is_writer {false};
0168 };
0169
0170 }
0171 }
0172 }
0173
0174 #endif