1/*
2 * Copyright (c) 2024 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 JS_CONCURRENT_MODULE_UTILS_LOCKS_LOCK_REQUEST_H
17#define JS_CONCURRENT_MODULE_UTILS_LOCKS_LOCK_REQUEST_H
18
19#include <queue>
20#include <string>
21#include "common.h"
22#include "helper/error_helper.h"
23#include "helper/napi_helper.h"
24#include "helper/object_helper.h"
25
26namespace Commonlibrary::Concurrent::LocksModule {
27enum LockMode {
28    LOCK_MODE_UNLOCK,
29    LOCK_MODE_SHARED,
30    LOCK_MODE_EXCLUSIVE,
31    LOCK_MODE_MAX
32};
33
34struct LockOptions {
35    bool isAvailable = false;
36    napi_ref signal = nullptr;
37    uint32_t timeoutMillis = 0;
38};
39
40class AsyncLock;
41
42class LockRequest {
43public:
44    LockRequest(AsyncLock* lock, tid_t tid, napi_env env, napi_ref cb, LockMode mode, const LockOptions &options,
45        napi_deferred deferred);
46    ~LockRequest();
47
48    tid_t GetTid() const
49    {
50        return tid_;
51    }
52
53    std::string GetCreationStacktrace()
54    {
55        return creationStacktrace_;
56    }
57
58    LockMode GetMode() const
59    {
60        return mode_;
61    }
62
63    const LockOptions &GetOptions() const
64    {
65        return options_;
66    }
67
68    napi_env GetEnv()
69    {
70        return env_;
71    }
72
73    void CallCallbackAsync();
74    void CallCallback();
75
76    void OnQueued(uint32_t timeoutMillis);
77    void OnSatisfied();
78private:
79    bool AbortIfNeeded();
80    void ArmTimeoutTimer(uint32_t timeoutMillis);
81    void DisarmTimeoutTimer();
82    void HandleRequestTimeout(std::string &&errorMessage);
83    std::string GetLockInfo() const;
84    void CleanTimer();
85    static void AsyncAfterWorkCallback(napi_env env, napi_status status, void *data);
86    static napi_value FinallyCallback(napi_env env, napi_callback_info info);
87    static void TimeoutCallback(uv_timer_t *handle);
88    static void DeallocateTimeoutTimerCallback(uv_handle_t* handle);
89    static void EnvCleanUp(void* arg);
90
91    AsyncLock* lock_;
92    tid_t tid_;
93    std::string creationStacktrace_;
94    napi_env env_;
95    napi_ref callback_;
96    LockMode mode_;
97    LockOptions options_;
98    napi_deferred deferred_;
99    napi_async_work work_;
100    uv_timer_t *timeoutTimer_;
101    bool timeoutActive_;
102    std::mutex lockRequestMutex_;
103};
104
105struct RequestTimeoutData {
106    RequestTimeoutData(AsyncLock* l, LockRequest* r): lock(l), request(r) {}
107    AsyncLock* lock;
108    LockRequest* request;
109};
110
111}  // namespace Commonlibrary::Concurrent::LocksModule
112#endif  // JS_CONCURRENT_MODULE_UTILS_LOCKS_LOCK_REQUEST_H
113