1 /*
2  * Copyright (C) 2021 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 
17 #ifndef MOCK_NATIVE_INCLUDE_RWLOCK_H
18 #define MOCK_NATIVE_INCLUDE_RWLOCK_H
19 
20 #include <atomic>
21 #include <thread>
22 
23 #include "nocopyable.h"
24 
25 namespace OHOS {
26 namespace Utils {
27 class RWLock : NoCopyable {
28 public:
29     enum LockStatus {
30         LOCK_STATUS_WRITE = -1,
31         LOCK_STATUS_FREE = 0,
32     };
33 
RWLock()34     RWLock() : RWLock(true) {}
35     explicit RWLock(bool writeFirst);
~RWLock()36     virtual ~RWLock() {}
37 
38     void LockRead();
39     void UnLockRead();
40 
41     void LockWrite();
42     void UnLockWrite();
43 
44 private:
45     bool writeFirst_;
46     std::thread::id writeThreadID_;
47 
48     // Resource lock counter, -1 is write state, 0 is free state, and greater than 0 is shared read state
49     std::atomic_int lockCount_;
50 
51     // Thread counter waiting for write lock
52     std::atomic_uint writeWaitCount_;
53 };
54 
55 template<typename RWLockable>
56 class UniqueWriteGuard : NoCopyable {
57 public:
UniqueWriteGuard(RWLockable & rwLockable)58     explicit UniqueWriteGuard(RWLockable &rwLockable)
59         : rwLockable_(rwLockable)
60     {
61         rwLockable_.LockWrite();
62     }
63 
~UniqueWriteGuard()64     ~UniqueWriteGuard() override
65     {
66         rwLockable_.UnLockWrite();
67     }
68 
69 private:
70     UniqueWriteGuard() = delete;
71 
72 private:
73     RWLockable &rwLockable_;
74 };
75 
76 
77 template<typename RWLockable>
78 class UniqueReadGuard : NoCopyable {
79 public:
UniqueReadGuard(RWLockable & rwLockable)80     explicit UniqueReadGuard(RWLockable &rwLockable)
81         : rwLockable_(rwLockable)
82     {
83         rwLockable_.LockRead();
84     }
85 
~UniqueReadGuard()86     ~UniqueReadGuard() override
87     {
88         rwLockable_.UnLockRead();
89     }
90 
91 private:
92     UniqueReadGuard() = delete;
93 
94 private:
95     RWLockable &rwLockable_;
96 };
97 } // namespace Utils
98 } // namespace OHOS
99 #endif // MOCK_NATIVE_INCLUDE_RWLOCK_H
100