1 /*
2 * Copyright (c) 2025 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 #include "condition_task.h"
17 #include "condition_variable.h"
18 #include "helper/napi_helper.h"
19 #include "helper/object_helper.h"
20 #include "tools/log.h"
21 #include "uv.h"
22
23 namespace Commonlibrary::Concurrent::Condition {
24
ConditionTask(ConditionVariable * cond,napi_env env,napi_deferred deferred,uint64_t timeout)25 ConditionTask::ConditionTask(ConditionVariable *cond, napi_env env, napi_deferred deferred, uint64_t timeout)
26 : cond_(cond), env_(env), deferred_(deferred)
27 {
28 AddEnvCleanupHook();
29 InitTimer(timeout);
30 }
31
~ConditionTask()32 ConditionTask::~ConditionTask()
33 {
34 CloseTimer();
35 }
36
GetEnv()37 napi_env ConditionTask::GetEnv()
38 {
39 return env_;
40 }
41
Finish(ConditionTaskFinishReason reason)42 void ConditionTask::Finish(ConditionTaskFinishReason reason)
43 {
44 switch (reason) {
45 case ConditionTaskFinishReason::NOTIFY:
46 StopTimer();
47 RemoveEnvCleanupHook();
48 ResolvePromise();
49 break;
50 case ConditionTaskFinishReason::TIMEOUT:
51 RemoveEnvCleanupHook();
52 ResolvePromise();
53 break;
54 case ConditionTaskFinishReason::ENV_CLEANUP:
55 StopTimer();
56 RejectPromise();
57 break;
58 }
59 delete this;
60 }
61
EnvCleanup(void * arg)62 void ConditionTask::EnvCleanup(void *arg)
63 {
64 ConditionTask *task {static_cast<ConditionTask *>(arg)};
65 task->cond_->FindAndFinishTask(task, ConditionTaskFinishReason::ENV_CLEANUP);
66 }
67
ResolvePromise()68 void ConditionTask::ResolvePromise()
69 {
70 napi_status status {napi_ok};
71 Common::Helper::HandleScope scope(env_, status);
72 NAPI_CALL_RETURN_VOID(env_, status);
73
74 napi_value result;
75 NAPI_CALL_RETURN_VOID(env_, napi_get_undefined(env_, &result));
76 NAPI_CALL_RETURN_VOID(env_, napi_resolve_deferred(env_, deferred_, result));
77 }
78
RejectPromise()79 void ConditionTask::RejectPromise()
80 {
81 napi_status status {napi_ok};
82 Common::Helper::HandleScope scope(env_, status);
83 NAPI_CALL_RETURN_VOID(env_, status);
84
85 napi_value result;
86 NAPI_CALL_RETURN_VOID(env_, napi_get_undefined(env_, &result));
87 NAPI_CALL_RETURN_VOID(env_, napi_reject_deferred(env_, deferred_, result));
88 }
89
InitTimer(uint64_t timeout)90 void ConditionTask::InitTimer(uint64_t timeout)
91 {
92 if (timeout < 0) {
93 return;
94 }
95 timer_ = new uv_timer_t;
96 uv_timer_init(Common::Helper::NapiHelper::GetLibUV(env_), timer_);
97 timer_->data = this;
98 uv_timer_start(
99 timer_,
100 [](uv_timer_t *timer) {
101 ConditionTask *task {static_cast<ConditionTask *>(timer->data)};
102 task->cond_->FindAndFinishTask(task, ConditionTaskFinishReason::TIMEOUT);
103 },
104 timeout, 0);
105 }
106
StopTimer()107 void ConditionTask::StopTimer()
108 {
109 if (timer_ == nullptr) {
110 return;
111 }
112 uv_timer_stop(timer_);
113 }
114
CloseTimer()115 void ConditionTask::CloseTimer()
116 {
117 if (timer_ == nullptr) {
118 return;
119 }
120 uv_close(reinterpret_cast<uv_handle_t *>(timer_), [](uv_handle_t *handle) { delete handle; });
121 }
122
AddEnvCleanupHook()123 void ConditionTask::AddEnvCleanupHook()
124 {
125 NAPI_CALL_RETURN_VOID(env_, napi_add_env_cleanup_hook(env_, EnvCleanup, this));
126 }
127
RemoveEnvCleanupHook()128 void ConditionTask::RemoveEnvCleanupHook()
129 {
130 NAPI_CALL_RETURN_VOID(env_, napi_remove_env_cleanup_hook(env_, EnvCleanup, this));
131 }
132
133 } // namespace Commonlibrary::Concurrent::Condition
134