1e5c4badcSopenharmony_ci/*
2e5c4badcSopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd.
3e5c4badcSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e5c4badcSopenharmony_ci * you may not use this file except in compliance with the License.
5e5c4badcSopenharmony_ci * You may obtain a copy of the License at
6e5c4badcSopenharmony_ci *
7e5c4badcSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e5c4badcSopenharmony_ci *
9e5c4badcSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e5c4badcSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e5c4badcSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e5c4badcSopenharmony_ci * See the License for the specific language governing permissions and
13e5c4badcSopenharmony_ci * limitations under the License.
14e5c4badcSopenharmony_ci */
15e5c4badcSopenharmony_ci
16e5c4badcSopenharmony_ci
17e5c4badcSopenharmony_ci#ifndef MOCK_NATIVE_INCLUDE_RWLOCK_H
18e5c4badcSopenharmony_ci#define MOCK_NATIVE_INCLUDE_RWLOCK_H
19e5c4badcSopenharmony_ci
20e5c4badcSopenharmony_ci#include <atomic>
21e5c4badcSopenharmony_ci#include <thread>
22e5c4badcSopenharmony_ci
23e5c4badcSopenharmony_ci#include "nocopyable.h"
24e5c4badcSopenharmony_ci
25e5c4badcSopenharmony_cinamespace OHOS {
26e5c4badcSopenharmony_cinamespace Utils {
27e5c4badcSopenharmony_ciclass RWLock : NoCopyable {
28e5c4badcSopenharmony_cipublic:
29e5c4badcSopenharmony_ci    enum LockStatus {
30e5c4badcSopenharmony_ci        LOCK_STATUS_WRITE = -1,
31e5c4badcSopenharmony_ci        LOCK_STATUS_FREE = 0,
32e5c4badcSopenharmony_ci    };
33e5c4badcSopenharmony_ci
34e5c4badcSopenharmony_ci    RWLock() : RWLock(true) {}
35e5c4badcSopenharmony_ci    explicit RWLock(bool writeFirst);
36e5c4badcSopenharmony_ci    virtual ~RWLock() {}
37e5c4badcSopenharmony_ci
38e5c4badcSopenharmony_ci    void LockRead();
39e5c4badcSopenharmony_ci    void UnLockRead();
40e5c4badcSopenharmony_ci
41e5c4badcSopenharmony_ci    void LockWrite();
42e5c4badcSopenharmony_ci    void UnLockWrite();
43e5c4badcSopenharmony_ci
44e5c4badcSopenharmony_ciprivate:
45e5c4badcSopenharmony_ci    bool writeFirst_;
46e5c4badcSopenharmony_ci    std::thread::id writeThreadID_;
47e5c4badcSopenharmony_ci
48e5c4badcSopenharmony_ci    // Resource lock counter, -1 is write state, 0 is free state, and greater than 0 is shared read state
49e5c4badcSopenharmony_ci    std::atomic_int lockCount_;
50e5c4badcSopenharmony_ci
51e5c4badcSopenharmony_ci    // Thread counter waiting for write lock
52e5c4badcSopenharmony_ci    std::atomic_uint writeWaitCount_;
53e5c4badcSopenharmony_ci};
54e5c4badcSopenharmony_ci
55e5c4badcSopenharmony_citemplate<typename RWLockable>
56e5c4badcSopenharmony_ciclass UniqueWriteGuard : NoCopyable {
57e5c4badcSopenharmony_cipublic:
58e5c4badcSopenharmony_ci    explicit UniqueWriteGuard(RWLockable &rwLockable)
59e5c4badcSopenharmony_ci        : rwLockable_(rwLockable)
60e5c4badcSopenharmony_ci    {
61e5c4badcSopenharmony_ci        rwLockable_.LockWrite();
62e5c4badcSopenharmony_ci    }
63e5c4badcSopenharmony_ci
64e5c4badcSopenharmony_ci    ~UniqueWriteGuard() override
65e5c4badcSopenharmony_ci    {
66e5c4badcSopenharmony_ci        rwLockable_.UnLockWrite();
67e5c4badcSopenharmony_ci    }
68e5c4badcSopenharmony_ci
69e5c4badcSopenharmony_ciprivate:
70e5c4badcSopenharmony_ci    UniqueWriteGuard() = delete;
71e5c4badcSopenharmony_ci
72e5c4badcSopenharmony_ciprivate:
73e5c4badcSopenharmony_ci    RWLockable &rwLockable_;
74e5c4badcSopenharmony_ci};
75e5c4badcSopenharmony_ci
76e5c4badcSopenharmony_ci
77e5c4badcSopenharmony_citemplate<typename RWLockable>
78e5c4badcSopenharmony_ciclass UniqueReadGuard : NoCopyable {
79e5c4badcSopenharmony_cipublic:
80e5c4badcSopenharmony_ci    explicit UniqueReadGuard(RWLockable &rwLockable)
81e5c4badcSopenharmony_ci        : rwLockable_(rwLockable)
82e5c4badcSopenharmony_ci    {
83e5c4badcSopenharmony_ci        rwLockable_.LockRead();
84e5c4badcSopenharmony_ci    }
85e5c4badcSopenharmony_ci
86e5c4badcSopenharmony_ci    ~UniqueReadGuard() override
87e5c4badcSopenharmony_ci    {
88e5c4badcSopenharmony_ci        rwLockable_.UnLockRead();
89e5c4badcSopenharmony_ci    }
90e5c4badcSopenharmony_ci
91e5c4badcSopenharmony_ciprivate:
92e5c4badcSopenharmony_ci    UniqueReadGuard() = delete;
93e5c4badcSopenharmony_ci
94e5c4badcSopenharmony_ciprivate:
95e5c4badcSopenharmony_ci    RWLockable &rwLockable_;
96e5c4badcSopenharmony_ci};
97e5c4badcSopenharmony_ci} // namespace Utils
98e5c4badcSopenharmony_ci} // namespace OHOS
99e5c4badcSopenharmony_ci#endif // MOCK_NATIVE_INCLUDE_RWLOCK_H
100