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 
26 namespace Commonlibrary::Concurrent::LocksModule {
27 enum LockMode {
28     LOCK_MODE_UNLOCK,
29     LOCK_MODE_SHARED,
30     LOCK_MODE_EXCLUSIVE,
31     LOCK_MODE_MAX
32 };
33 
34 struct LockOptions {
35     bool isAvailable = false;
36     napi_ref signal = nullptr;
37     uint32_t timeoutMillis = 0;
38 };
39 
40 class AsyncLock;
41 
42 class LockRequest {
43 public:
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 
GetTid() const48     tid_t GetTid() const
49     {
50         return tid_;
51     }
52 
GetCreationStacktrace()53     std::string GetCreationStacktrace()
54     {
55         return creationStacktrace_;
56     }
57 
GetMode() const58     LockMode GetMode() const
59     {
60         return mode_;
61     }
62 
GetOptions() const63     const LockOptions &GetOptions() const
64     {
65         return options_;
66     }
67 
GetEnv()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();
78 private:
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 
105 struct RequestTimeoutData {
RequestTimeoutDataCommonlibrary::Concurrent::LocksModule::RequestTimeoutData106     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