• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
33 namespace panda::ecmascript {
34 
35 class PUBLIC_API Mutex {
36 public:
37     explicit  Mutex(bool is_init = true);
38 
39     ~Mutex();
40 
41     void Lock();
42 
43     bool TryLock();
44 
45     void Unlock();
46 
47 protected:
48     void Init(pthread_mutexattr_t *attrs);
49 
50 private:
51     pthread_mutex_t mutex_;
52     friend class ConditionVariable;
53 };
54 
55 class RecursiveMutex : public Mutex {
56 public:
57     RecursiveMutex();
58 
59     ~RecursiveMutex() = default;
60 
61     NO_COPY_SEMANTIC(RecursiveMutex);
62     NO_MOVE_SEMANTIC(RecursiveMutex);
63 };
64 
65 class RWLock {
66 public:
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 
81 private:
82     pthread_rwlock_t rwlock_;
83 
84     NO_COPY_SEMANTIC(RWLock);
85     NO_MOVE_SEMANTIC(RWLock);
86 };
87 
88 class PUBLIC_API ConditionVariable {
89 public:
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 
102 private:
103     pthread_cond_t cond_;
104 };
105 
106 class LockHolder {
107 public:
LockHolder(Mutex & mtx)108     explicit LockHolder(Mutex &mtx) : lock_(mtx)
109     {
110         lock_.Lock();
111     }
112 
~LockHolder()113     ~LockHolder()
114     {
115         lock_.Unlock();
116     }
117 
118 private:
119     Mutex &lock_;
120 
121     NO_COPY_SEMANTIC(LockHolder);
122     NO_MOVE_SEMANTIC(LockHolder);
123 };
124 
125 class ReadLockHolder {
126 public:
ReadLockHolder(RWLock & lock)127     explicit ReadLockHolder(RWLock &lock) : lock_(lock)
128     {
129         lock_.ReadLock();
130     }
131 
~ReadLockHolder()132     ~ReadLockHolder()
133     {
134         lock_.Unlock();
135     }
136 
137 private:
138     RWLock &lock_;
139 
140     NO_COPY_SEMANTIC(ReadLockHolder);
141     NO_MOVE_SEMANTIC(ReadLockHolder);
142 };
143 
144 class WriteLockHolder {
145 public:
WriteLockHolder(RWLock & lock)146     explicit WriteLockHolder(RWLock &lock) : lock_(lock)
147     {
148         lock_.WriteLock();
149     }
150 
~WriteLockHolder()151     ~WriteLockHolder()
152     {
153         lock_.Unlock();
154     }
155 
156 private:
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