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