Shaka Player Embedded
shared_lock.h
Go to the documentation of this file.
1 // Copyright 2018 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SHAKA_EMBEDDED_UTIL_SHARED_LOCK_H_
16 #define SHAKA_EMBEDDED_UTIL_SHARED_LOCK_H_
17 
18 #ifdef USE_PTHREAD
19 # include <pthread.h>
20 #else
21 # include <condition_variable>
22 # include <mutex>
23 #endif
24 
25 #include <utility>
26 
27 #include "src/util/macros.h"
28 
29 namespace shaka {
30 namespace util {
31 
57 class shared_mutex {
58  public:
59  shared_mutex();
60  ~shared_mutex();
61 
63 
65  void lock() {
66  maybe_try_lock(/* only_try */ false);
67  }
68 
70  bool try_lock() {
71  return maybe_try_lock(/* only_try */ true);
72  }
73 
75  void unlock();
76 
77 
79  void lock_shared() {
80  maybe_try_lock_shared(/* only_try */ false);
81  }
82 
84  bool try_lock_shared() {
85  return maybe_try_lock_shared(/* only_try */ true);
86  }
87 
89  void unlock_shared();
90 
91  private:
92  bool maybe_try_lock(bool only_try);
93  bool maybe_try_lock_shared(bool only_try);
94 
95 #ifdef USE_PTHREAD
96  pthread_rwlock_t lock_;
97 #else
98  std::mutex mutex_;
99  std::condition_variable signal_;
100  uint32_t shared_count_ = 0;
101  bool is_exclusive_ = false;
102  bool is_exclusive_waiting_ = false;
103 #endif
104 };
105 
106 
111 template <typename Mutex>
112 class shared_lock {
113  public:
114  using mutex_type = Mutex;
115 
116  shared_lock() : mutex_(nullptr), owns_lock_(false) {}
117  explicit shared_lock(mutex_type& mutex) : mutex_(&mutex) {
118  mutex_->lock_shared();
119  owns_lock_ = true;
120  }
122  : mutex_(other.mutex_), owns_lock_(other.owns_lock_) {
123  other.mutex_ = nullptr;
124  other.owns_lock_ = false;
125  }
126 
128  if (owns_lock_)
129  mutex_->unlock_shared();
130  }
131 
133 
135  other.swap(*this);
136  return *this;
137  }
138 
139  operator bool() const { return owns_lock_; }
140  bool owns_lock() const { return owns_lock_; }
141  mutex_type* mutex() const { return mutex_; }
142 
143  void swap(shared_lock& other) {
144  swap(mutex_, other.mutex_);
145  swap(owns_lock_, other.owns_lock_);
146  }
147 
149  Mutex* ret = mutex_;
150  mutex_ = nullptr;
151  owns_lock_ = false;
152  return ret;
153  }
154 
155  private:
156  mutex_type* mutex_;
157  bool owns_lock_;
158 };
159 
160 template <typename Mutex>
162  a.swap(b);
163 }
164 
165 } // namespace util
166 } // namespace shaka
167 
168 #endif // SHAKA_EMBEDDED_UTIL_SHARED_LOCK_H_
mutex_type * mutex() const
Definition: shared_lock.h:141
mutex_type * release()
Definition: shared_lock.h:148
shared_lock(mutex_type &mutex)
Definition: shared_lock.h:117
void swap(shared_lock &other)
Definition: shared_lock.h:143
shared_lock & operator=(shared_lock &&other)
Definition: shared_lock.h:134
void swap(shared_lock< Mutex > &a, shared_lock< Mutex > &b)
Definition: shared_lock.h:161
#define SHAKA_NON_COPYABLE_TYPE(Type)
Definition: macros.h:43
SHAKA_NON_COPYABLE_OR_MOVABLE_TYPE(shared_mutex)
shared_lock(shared_lock &&other)
Definition: shared_lock.h:121