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