• 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 "napi/native_api.h"
17 #include <native_fence/native_fence.h>
18 
19 #include <chrono>
20 #include <cstring>
21 #include <cerrno>
22 #include <fcntl.h>
23 #include <iostream>
24 #include <csignal>
25 #include <sys/ioctl.h>
26 #include <sys/signalfd.h>
27 #include <thread>
28 #include <unistd.h>
29 #include "common/log_common.h"
30 
31 #define SUCCESS 0
32 #define FAIL (-1)
33 
34 constexpr int INVALID_FD = -1;
35 constexpr uint32_t TIMEOUT_ZE = 0;
36 constexpr uint32_t TIMEOUT_FH = 500;
37 constexpr uint32_t TIMEOUT_FT = 5000;
38 
NativeFenceWaitIs0(napi_env env,napi_callback_info info)39 static napi_value NativeFenceWaitIs0(napi_env env, napi_callback_info info)
40 {
41     napi_value res = nullptr;
42     bool result = OH_NativeFence_Wait(INVALID_FD, TIMEOUT_FT);
43     if (result) {
44         napi_create_int32(env, 1, &res); // 1 Mark the incorrect location
45         return res;
46     }
47     bool isValid = OH_NativeFence_IsValid(INVALID_FD);
48     if (isValid) {
49         napi_create_int32(env, 2, &res); // 2 Mark the incorrect location
50         return res;
51     }
52     sigset_t mask;
53     sigemptyset(&mask);
54     sigaddset(&mask, SIGINT); // Monitor SIGINT signal (Ctrl C)
55     sigaddset(&mask, SIGURG); // Monitor SIGURG signal (Emergency event)
56     sigprocmask(SIG_BLOCK, &mask, nullptr);
57     int sfd = signalfd(-1, &mask, 0);
58     if (sfd == -1) {
59         perror("signalfd failed");
60         exit(1);
61     }
62     isValid = OH_NativeFence_IsValid(sfd);
63     if (!isValid) {
64         napi_create_int32(env, 3, &res); // 3 Mark the incorrect location
65         return res;
66     }
67     bool result2 = false;
68     result2 = OH_NativeFence_Wait(sfd, TIMEOUT_ZE);
69     if (result2) {
70         napi_create_int32(env, 4, &res); // 4 Mark the incorrect location
71         return res;
72     }
73     OH_NativeFence_Close(sfd);
74     napi_create_int32(env, SUCCESS, &res);
75     return res;
76 }
77 
NativeFenceWaitIs500(napi_env env,napi_callback_info info)78 static napi_value NativeFenceWaitIs500(napi_env env, napi_callback_info info)
79 {
80     napi_value res = nullptr;
81     sigset_t mask;
82     sigemptyset(&mask);
83     sigaddset(&mask, SIGINT); // Monitor SIGINT signal (Ctrl C)
84     sigaddset(&mask, SIGURG); // Monitor SIGURG signal (Emergency event)
85     sigprocmask(SIG_BLOCK, &mask, nullptr);
86     int sfd = signalfd(-1, &mask, 0);
87     if (sfd == -1) {
88         perror("signalfd failed");
89         exit(1);
90     }
91     bool isValid = OH_NativeFence_IsValid(sfd);
92     if (!isValid) {
93         napi_create_int32(env, 1, &res); // 1 Mark the incorrect location
94         return res;
95     }
96     bool result2 = false;
97     result2 = OH_NativeFence_Wait(sfd, TIMEOUT_FH);
98     if (result2) {
99         napi_create_int32(env, 2, &res); // 2 Mark the incorrect location
100         return res;
101     }
102     OH_NativeFence_Close(sfd);
103     napi_create_int32(env, SUCCESS, &res);
104     return res;
105 }
106 
NativeFenceWaitIs5000(napi_env env,napi_callback_info info)107 static napi_value NativeFenceWaitIs5000(napi_env env, napi_callback_info info)
108 {
109     napi_value res = nullptr;
110     sigset_t mask;
111     sigemptyset(&mask);
112     sigaddset(&mask, SIGINT); // Monitor SIGINT signal (Ctrl C)
113     sigaddset(&mask, SIGURG); // Monitor SIGURG signal (Emergency event)
114     sigprocmask(SIG_BLOCK, &mask, nullptr);
115     int sfd = signalfd(-1, &mask, 0);
116     if (sfd == -1) {
117         perror("signalfd failed");
118         exit(1);
119     }
120     bool isValid = OH_NativeFence_IsValid(sfd);
121     if (!isValid) {
122         napi_create_int32(env, 1, &res); // 1 Mark the incorrect location
123         return res;
124     }
125     bool result2 = false;
126     result2 = OH_NativeFence_Wait(sfd, TIMEOUT_FT);
127     if (result2) {
128         napi_create_int32(env, 2, &res); // 2 Mark the incorrect location
129         return res;
130     }
131     OH_NativeFence_Close(sfd);
132     napi_create_int32(env, SUCCESS, &res);
133     return res;
134 }
135 
NativeFenceWaitKill(napi_env env,napi_callback_info info)136 static napi_value NativeFenceWaitKill(napi_env env, napi_callback_info info)
137 {
138     napi_value res = nullptr;
139     std::atomic<bool> signaled(false);
140     sigset_t mask;
141     sigemptyset(&mask);
142     sigaddset(&mask, SIGINT); // Monitor SIGINT signal (Ctrl C)
143     sigaddset(&mask, SIGURG); // Monitor SIGURG signal (Emergency event)
144     sigprocmask(SIG_BLOCK, &mask, nullptr);
145     int sfd = signalfd(-1, &mask, 0);
146     if (sfd == -1) {
147         perror("signalfd failed");
148         exit(1);
149     }
150     bool result = false;
151     std::thread waitThread([&result, sfd, &signaled]() {
152         result = OH_NativeFence_Wait(sfd, TIMEOUT_FT);
153         signaled.store(true);
154     });
155     std::this_thread::sleep_for(std::chrono::seconds(3)); // 3 means main thread sleep 3 seconds.
156     pthread_kill(waitThread.native_handle(), SIGURG);
157     // Waiting for waitThread to complete
158     waitThread.join();
159     bool isValid = OH_NativeFence_IsValid(sfd);
160     if (!isValid) {
161         napi_create_int32(env, 1, &res); // 1 Mark the incorrect location
162         return res;
163     }
164     if (!result) {
165         napi_create_int32(env, 2, &res); // 2 Mark the incorrect location
166         return res;
167     }
168     // checks the signaled variable to ensure that OH_NativeFence_Wait has returned
169     if (!signaled.load()) {
170         napi_create_int32(env, FAIL, &res);
171         return res;
172     }
173     OH_NativeFence_Close(sfd);
174     napi_create_int32(env, SUCCESS, &res);
175     return res;
176 }
177 
NativeFenceWaitForeverKill(napi_env env,napi_callback_info info)178 static napi_value NativeFenceWaitForeverKill(napi_env env, napi_callback_info info)
179 {
180     napi_value res = nullptr;
181     bool result = OH_NativeFence_WaitForever(INVALID_FD);
182     if (result) {
183         napi_create_int32(env, 1, &res); // 1 Mark the incorrect location
184         return res;
185     }
186     std::atomic<bool> signaled(false);
187     sigset_t mask;
188     sigemptyset(&mask);
189     sigaddset(&mask, SIGINT); // Monitor SIGINT signal (Ctrl C)
190     sigaddset(&mask, SIGTTIN); // Monitor SIGURG signal (The background job reads data from the user terminal)
191     sigprocmask(SIG_BLOCK, &mask, nullptr);
192     int sfd = signalfd(-1, &mask, 0);
193     if (sfd == -1) {
194         perror("signalfd failed");
195         exit(1);
196     }
197     bool result2 = false;
198     std::thread waitThread([&result2, sfd, &signaled]() {
199         result2 = OH_NativeFence_WaitForever(sfd);
200         signaled.store(true);
201     });
202     std::this_thread::sleep_for(std::chrono::seconds(3)); // 3 means main thread sleep 3 seconds.
203     pthread_kill(waitThread.native_handle(), SIGTTIN);
204     // Waiting for waitThread to complete
205     waitThread.join();
206     if (!result2) {
207         napi_create_int32(env, 1, &res); // 1 Mark the incorrect location
208         return res;
209         }
210     bool isValid = OH_NativeFence_IsValid(sfd);
211     if (!isValid) {
212         napi_create_int32(env, 2, &res); // 2 Mark the incorrect location
213         return res;
214     }
215     // checks the signaled variable to ensure that OH_NativeFence_Wait has returned
216     if (!signaled.load()) {
217         napi_create_int32(env, FAIL, &res);
218         return res;
219     }
220     OH_NativeFence_Close(sfd);
221     napi_create_int32(env, SUCCESS, &res);
222     return res;
223 }
224 
225 // EXTERN_C_START
Init(napi_env env,napi_value exports)226 static napi_value Init(napi_env env, napi_value exports)
227 {
228     napi_property_descriptor desc[] = {
229         { "nativeFenceWaitIs0", nullptr, NativeFenceWaitIs0, nullptr, nullptr, nullptr, napi_default, nullptr },
230         { "nativeFenceWaitIs500", nullptr, NativeFenceWaitIs500, nullptr, nullptr, nullptr, napi_default, nullptr },
231         { "nativeFenceWaitIs5000", nullptr, NativeFenceWaitIs5000, nullptr, nullptr, nullptr, napi_default, nullptr },
232         { "nativeFenceWaitKill", nullptr, NativeFenceWaitKill, nullptr, nullptr, nullptr, napi_default, nullptr },
233         { "nativeFenceWaitForeverKill", nullptr,
234             NativeFenceWaitForeverKill, nullptr, nullptr, nullptr, napi_default, nullptr },
235     };
236     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
237     return exports;
238 }
239 // EXTERN_C_END
240 
241 static napi_module demoModule = {
242     .nm_version = 1,
243     .nm_flags = 0,
244     .nm_filename = nullptr,
245     .nm_register_func = Init,
246     .nm_modname = "nativefence",
247     .nm_priv = ((void*)0),
248     .reserved = { 0 },
249 };
250 
RegisterEntryModule(void)251 extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
252 {
253     napi_module_register(&demoModule);
254 }