• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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