1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 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 * http://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 16 #ifndef ECMASCRIPT_PLATFORM_MUTEX_H 17 #define ECMASCRIPT_PLATFORM_MUTEX_H 18 19 #include <pthread.h> 20 21 #include "ecmascript/common.h" 22 23 namespace panda::ecmascript { 24 25 class PUBLIC_API Mutex { 26 public: 27 explicit Mutex(bool is_init = true); 28 29 ~Mutex(); 30 31 void Lock(); 32 33 bool TryLock(); 34 35 void Unlock(); 36 37 protected: 38 void Init(pthread_mutexattr_t *attrs); 39 40 private: 41 pthread_mutex_t mutex_; 42 43 NO_COPY_SEMANTIC(Mutex); 44 NO_MOVE_SEMANTIC(Mutex); 45 46 friend class ConditionVariable; 47 }; 48 49 class RecursiveMutex : public Mutex { 50 public: 51 RecursiveMutex(); 52 53 ~RecursiveMutex() = default; 54 55 NO_COPY_SEMANTIC(RecursiveMutex); 56 NO_MOVE_SEMANTIC(RecursiveMutex); 57 }; 58 59 class RWLock { 60 public: 61 RWLock(); 62 63 ~RWLock(); 64 65 void ReadLock(); 66 67 void WriteLock(); 68 69 bool TryReadLock(); 70 71 bool TryWriteLock(); 72 73 void Unlock(); 74 75 private: 76 pthread_rwlock_t rwlock_; 77 78 NO_COPY_SEMANTIC(RWLock); 79 NO_MOVE_SEMANTIC(RWLock); 80 }; 81 82 class PUBLIC_API ConditionVariable { 83 public: 84 ConditionVariable(); 85 86 ~ConditionVariable(); 87 88 void Signal(); 89 90 void SignalAll(); 91 92 void Wait(Mutex *mutex); 93 94 bool TimedWait(Mutex *mutex, uint64_t ms, uint64_t ns = 0, bool is_absolute = false); 95 96 private: 97 pthread_cond_t cond_; 98 99 NO_COPY_SEMANTIC(ConditionVariable); 100 NO_MOVE_SEMANTIC(ConditionVariable); 101 }; 102 103 class LockHolder { 104 public: LockHolder(Mutex & mtx)105 explicit LockHolder(Mutex &mtx) : lock_(mtx) 106 { 107 lock_.Lock(); 108 } 109 ~LockHolder()110 ~LockHolder() 111 { 112 lock_.Unlock(); 113 } 114 115 private: 116 Mutex &lock_; 117 118 NO_COPY_SEMANTIC(LockHolder); 119 NO_MOVE_SEMANTIC(LockHolder); 120 }; 121 122 class ReadLockHolder { 123 public: ReadLockHolder(RWLock & lock)124 explicit ReadLockHolder(RWLock &lock) : lock_(lock) 125 { 126 lock_.ReadLock(); 127 } 128 ~ReadLockHolder()129 ~ReadLockHolder() 130 { 131 lock_.Unlock(); 132 } 133 134 private: 135 RWLock &lock_; 136 137 NO_COPY_SEMANTIC(ReadLockHolder); 138 NO_MOVE_SEMANTIC(ReadLockHolder); 139 }; 140 141 class WriteLockHolder { 142 public: WriteLockHolder(RWLock & lock)143 explicit WriteLockHolder(RWLock &lock) : lock_(lock) 144 { 145 lock_.WriteLock(); 146 } 147 ~WriteLockHolder()148 ~WriteLockHolder() 149 { 150 lock_.Unlock(); 151 } 152 153 private: 154 RWLock &lock_; 155 156 NO_COPY_SEMANTIC(WriteLockHolder); 157 NO_MOVE_SEMANTIC(WriteLockHolder); 158 }; 159 } // namespace panda::ecmascript 160 #endif // ECMASCRIPT_PLATFORM_MUTEX_H 161