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
25namespace OHOS {
26namespace Utils {
27class RWLock : NoCopyable {
28public:
29    enum LockStatus {
30        LOCK_STATUS_WRITE = -1,
31        LOCK_STATUS_FREE = 0,
32    };
33
34    RWLock() : RWLock(true) {}
35    explicit RWLock(bool writeFirst);
36    virtual ~RWLock() {}
37
38    void LockRead();
39    void UnLockRead();
40
41    void LockWrite();
42    void UnLockWrite();
43
44private:
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
55template<typename RWLockable>
56class UniqueWriteGuard : NoCopyable {
57public:
58    explicit UniqueWriteGuard(RWLockable &rwLockable)
59        : rwLockable_(rwLockable)
60    {
61        rwLockable_.LockWrite();
62    }
63
64    ~UniqueWriteGuard() override
65    {
66        rwLockable_.UnLockWrite();
67    }
68
69private:
70    UniqueWriteGuard() = delete;
71
72private:
73    RWLockable &rwLockable_;
74};
75
76
77template<typename RWLockable>
78class UniqueReadGuard : NoCopyable {
79public:
80    explicit UniqueReadGuard(RWLockable &rwLockable)
81        : rwLockable_(rwLockable)
82    {
83        rwLockable_.LockRead();
84    }
85
86    ~UniqueReadGuard() override
87    {
88        rwLockable_.UnLockRead();
89    }
90
91private:
92    UniqueReadGuard() = delete;
93
94private:
95    RWLockable &rwLockable_;
96};
97} // namespace Utils
98} // namespace OHOS
99#endif // MOCK_NATIVE_INCLUDE_RWLOCK_H
100