1 /*
2 * Copyright (c) 2021-2022 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 "test.h"
17
18 #include <uv.h>
19
20 #include "napi/native_api.h"
21 #include "napi/native_node_api.h"
22 #include "securec.h"
23 #include "utils/log.h"
24
25 struct CallJsCbData_t {
26 int32_t id = 0;
27 bool secondaryThread = false;
28 napi_threadsafe_function_call_mode blockOnFull = napi_tsfn_nonblocking;
29 };
30
31 struct FinalCbData_t {
32 int32_t id = 0;
33 };
34
35 static constexpr int32_t SEND_DATA_TEST = 11;
36 static constexpr int32_t CALL_JS_CB_DATA_TEST_ID = 101;
37 static constexpr int32_t FINAL_CB_DATA_TEST_ID = 1001;
38 static constexpr int32_t SEND_DATAS_LENGTH = 10;
39 static constexpr int32_t THREAD_COUNT = 2;
40 static constexpr int32_t THREAD_COUNT_FOUR = 4;
41 static constexpr int32_t MAX_QUEUE_SIZE = 3;
42 static constexpr int32_t SUCCESS_COUNT_JS_FOUR = 4;
43
44 static pid_t g_mainTid = 0;
45 static CallJsCbData_t g_jsData;
46 static CallJsCbData_t g_jsDataInternal;
47 static FinalCbData_t g_finalData;
48 static int32_t g_sendData = 0;
49 static uv_thread_t g_uvThread;
50 static uv_thread_t g_uvThreadTest5;
51 static uv_thread_t g_uvThreadTest6;
52 static uv_thread_t g_uvThreadTest7;
53 static uv_thread_t g_uvThreadSecondary;
54 static uv_thread_t g_uvTheads2;
55 static uv_thread_t g_uvTheads3;
56 static int32_t g_sendDatas[SEND_DATAS_LENGTH];
57 static int32_t callSuccessCount = 0;
58 static int32_t callSuccessCountJS = 0;
59 static int32_t callSuccessCountJSFour = 0;
60 bool acquireFlag = false;
61
TsFuncCallJs(napi_env env,napi_value tsfn_cb,void * context,void * data)62 static void TsFuncCallJs(napi_env env, napi_value tsfn_cb, void* context, void* data)
63 {
64 HILOG_INFO("TsFuncCallJs called");
65
66 EXPECT_EQ(gettid(), g_mainTid);
67
68 // expect context equal
69 EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID);
70
71 // expect data equal
72 int* pData = (int32_t*)data;
73 EXPECT_EQ((*pData), SEND_DATA_TEST);
74 }
TsFuncCallJsTwo(napi_env env,napi_value tsfn_cb,void * context,void * data)75 static void TsFuncCallJsTwo(napi_env env, napi_value tsfn_cb, void* context, void* data)
76 {
77 HILOG_INFO("TsFuncCallJsTwo called");
78 TsFuncCallJs(env, tsfn_cb, context, data);
79 callSuccessCountJS++;
80 }
TsFuncCallJsFour(napi_env env,napi_value tsfn_cb,void * context,void * data)81 static void TsFuncCallJsFour(napi_env env, napi_value tsfn_cb, void* context, void* data)
82 {
83 HILOG_INFO("TsFuncCallJsFour called");
84
85 TsFuncCallJs(env, tsfn_cb, context, data);
86 callSuccessCountJSFour++;
87 }
TsFuncCallJsMulti(napi_env env,napi_value tsfn_cb,void * context,void * data)88 static void TsFuncCallJsMulti(napi_env env,
89 napi_value tsfn_cb,
90 void* context,
91 void* data)
92 {
93 HILOG_INFO("TsFuncCallJsMulti called");
94
95 EXPECT_EQ(gettid(), g_mainTid);
96
97 // expect context equal
98 EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID);
99
100 int* pData = ((int32_t*)data);
101
102 HILOG_INFO("TsFuncCallJsMulti data %d", (*pData));
103 }
104
TsFuncFinal(napi_env env,void * finalizeData,void * hint)105 static void TsFuncFinal(napi_env env, void* finalizeData, void* hint)
106 {
107 HILOG_INFO("TsFuncFinal called");
108
109 // expect thread id equal
110 EXPECT_EQ(gettid(), g_mainTid);
111
112 // wait data source thread
113 uv_thread_join(&g_uvThread);
114
115 // expect context equal
116 EXPECT_EQ(((CallJsCbData_t*)hint)->id, CALL_JS_CB_DATA_TEST_ID);
117
118 // expect finalize data equal
119 EXPECT_EQ(((FinalCbData_t*)finalizeData)->id, FINAL_CB_DATA_TEST_ID);
120 }
TsFuncFinalTest5(napi_env env,void * finalizeData,void * hint)121 static void TsFuncFinalTest5(napi_env env, void* finalizeData, void* hint)
122 {
123 HILOG_INFO("TsFuncFinalTest5 called");
124
125 // expect thread id equal
126 EXPECT_EQ(gettid(), g_mainTid);
127
128 // wait data source thread
129 uv_thread_join(&g_uvThreadTest5);
130
131 // expect context equal
132 EXPECT_EQ(((CallJsCbData_t*)hint)->id, CALL_JS_CB_DATA_TEST_ID);
133
134 // expect finalize data equal
135 EXPECT_EQ(((FinalCbData_t*)finalizeData)->id, FINAL_CB_DATA_TEST_ID);
136 }
TsFuncFinalTotal(napi_env env,void * finalizeData,void * hint)137 static void TsFuncFinalTotal(napi_env env, void* finalizeData, void* hint)
138 {
139 HILOG_INFO("TsFuncFinalTotal called");
140 uv_thread_join(&g_uvThreadTest6);
141 // when add thread,repair callSuccessCountJS eq SUCCESS_COUNT_JS_TWO
142 EXPECT_EQ(callSuccessCountJS, SUCCESS_COUNT_JS_FOUR);
143 HILOG_INFO("TsFuncFinalTotal end");
144 }
TsFuncFinalTotalFour(napi_env env,void * finalizeData,void * hint)145 static void TsFuncFinalTotalFour(napi_env env, void* finalizeData, void* hint)
146 {
147 HILOG_INFO("TsFuncFinalTotalFour called");
148 uv_thread_join(&g_uvThreadTest7);
149 EXPECT_EQ(callSuccessCountJSFour, SUCCESS_COUNT_JS_FOUR);
150 HILOG_INFO("TsFuncFinalTotalFour end");
151 }
152
TsFuncFinalJoinThread(napi_env env,void * data,void * hint)153 static void TsFuncFinalJoinThread(napi_env env, void* data, void* hint)
154 {
155 HILOG_INFO("TsFuncFinalJoinThread called");
156
157 uv_thread_t *uvThread = reinterpret_cast<uv_thread_t*>(data);
158 CallJsCbData_t *jsData = reinterpret_cast<CallJsCbData_t*>(hint);
159
160 uv_thread_join(uvThread);
161
162 if (jsData->secondaryThread) {
163 uv_thread_join(&g_uvThreadSecondary);
164 }
165 }
166
TsFuncSecondaryThread(void * data)167 static void TsFuncSecondaryThread(void* data)
168 {
169 HILOG_INFO("TsFuncSecondaryThread called");
170
171 // expect thread id not equal
172 EXPECT_NE(gettid(), g_mainTid);
173
174 napi_threadsafe_function func = (napi_threadsafe_function)data;
175
176 auto status = napi_release_threadsafe_function(func, napi_tsfn_release);
177 EXPECT_EQ(status, napi_ok);
178 }
179
TsFuncDataSourceThread(void * data)180 static void TsFuncDataSourceThread(void* data)
181 {
182 HILOG_INFO("TsFuncDataSourceThread called");
183
184 // expect thread id not equal
185 EXPECT_NE(gettid(), g_mainTid);
186
187 napi_threadsafe_function func = (napi_threadsafe_function)data;
188 napi_threadsafe_function_call_mode blockMode = napi_tsfn_nonblocking;
189 void* context = nullptr;
190
191 auto status = napi_get_threadsafe_function_context(func, &context);
192 EXPECT_EQ(status, napi_ok);
193
194 // expect context equal
195 EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID);
196
197 // set send data
198 g_sendData = SEND_DATA_TEST;
199
200 // As main thread has set initial_thread_count to 1 and only this one secondary thread,
201 // so no need to call `napi_acquire_threadsafe_function()`.
202 status = napi_call_threadsafe_function(func, &g_sendData, blockMode);
203 EXPECT_EQ(status, napi_ok);
204
205 status = napi_release_threadsafe_function(func, napi_tsfn_release);
206 EXPECT_EQ(status, napi_ok);
207 }
TsFuncDataSourceThreadAbort(void * data)208 static void TsFuncDataSourceThreadAbort(void* data)
209 {
210 HILOG_INFO("TsFuncDataSourceThreadAbort called");
211
212 // expect thread id not equal
213 EXPECT_NE(gettid(), g_mainTid);
214
215 napi_threadsafe_function func = (napi_threadsafe_function)data;
216 napi_threadsafe_function_call_mode blockMode = napi_tsfn_nonblocking;
217 void* context = nullptr;
218
219 auto status = napi_get_threadsafe_function_context(func, &context);
220 EXPECT_EQ(status, napi_ok);
221
222 // expect context equal
223 EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID);
224
225 // set send data
226 g_sendData = SEND_DATA_TEST;
227
228 status = napi_call_threadsafe_function(func, &g_sendData, blockMode);
229 EXPECT_EQ(status, napi_closing);
230 }
231
TsFuncDataSourceThreadCountTotal(void * data)232 static void TsFuncDataSourceThreadCountTotal(void* data)
233 {
234 HILOG_INFO("TsFuncDataSourceThreadCountTotal called");
235
236 // expect thread id not equal
237 EXPECT_NE(gettid(), g_mainTid);
238
239 napi_threadsafe_function func = (napi_threadsafe_function)data;
240 napi_threadsafe_function_call_mode blockMode = napi_tsfn_nonblocking;
241 void* context = nullptr;
242
243 auto status = napi_get_threadsafe_function_context(func, &context);
244 EXPECT_EQ(status, napi_ok);
245
246 // expect context equal
247 EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID);
248 // set send data
249 g_sendData = SEND_DATA_TEST;
250 if (acquireFlag) {
251 std::cout<<"acquireFlag is true"<<std::endl;
252 status = napi_acquire_threadsafe_function(func);
253 EXPECT_EQ(status, napi_ok);
254 status = napi_call_threadsafe_function(func, &g_sendData, blockMode);
255 if (status == napi_ok) {
256 callSuccessCount++;
257 }
258 status = napi_release_threadsafe_function(func, napi_tsfn_release);
259 } else {
260 status = napi_call_threadsafe_function(func, &g_sendData, blockMode);
261 if (status == napi_ok) {
262 callSuccessCount++;
263 }
264 }
265 status = napi_release_threadsafe_function(func, napi_tsfn_release);
266 }
267
TsFuncDataSourceThreadMulti(void * data)268 static void TsFuncDataSourceThreadMulti(void* data)
269 {
270 HILOG_INFO("TsFuncDataSourceThreadMulti called");
271
272 // expect thread id not equal
273 EXPECT_NE(gettid(), g_mainTid);
274
275 napi_threadsafe_function func = (napi_threadsafe_function)data;
276 void* context = nullptr;
277
278 auto status = napi_get_threadsafe_function_context(func, &context);
279 EXPECT_EQ(status, napi_ok);
280 CallJsCbData_t* jsData = nullptr;
281 jsData = (CallJsCbData_t*)context;
282
283 if (jsData->secondaryThread) {
284 status = napi_acquire_threadsafe_function(func);
285 EXPECT_EQ(status, napi_ok);
286
287 if (uv_thread_create(&g_uvThreadSecondary, TsFuncSecondaryThread, func) != 0) {
288 HILOG_ERROR("Failed to create uv thread!");
289 }
290 }
291
292 bool queueClosing = false;
293 bool queueFull = false;
294 int32_t index = 0;
295 for (index = SEND_DATAS_LENGTH - 1; index > -1 && !queueClosing; index--) {
296 g_sendDatas[index] = index;
297 status = napi_call_threadsafe_function(func, &g_sendDatas[index], jsData->blockOnFull);
298 HILOG_INFO("napi_call_threadsafe_function index %d status %d", index, status);
299
300 switch (status) {
301 case napi_queue_full:
302 queueFull = true;
303 index++;
304 [[fallthrough]];
305 case napi_ok:
306 continue;
307 case napi_closing:
308 queueClosing = true;
309 break;
310 default:
311 HILOG_ERROR("Failed to call napi_call_threadsafe_function!");
312 }
313 }
314
315 if (!queueClosing && (napi_release_threadsafe_function(func, napi_tsfn_release) != napi_ok)) {
316 HILOG_ERROR("Failed to call napi_release_threadsafe_function!");
317 }
318 }
319
TsFuncThreadInternal(napi_env env,napi_threadsafe_function_call_js cb,uv_thread_t & uvThread,bool secondary,bool block)320 static void TsFuncThreadInternal(napi_env env,
321 napi_threadsafe_function_call_js cb,
322 uv_thread_t& uvThread,
323 bool secondary,
324 bool block)
325 {
326 HILOG_INFO("TsFuncThreadInternal start secondary %d block %d", secondary, block);
327
328 napi_threadsafe_function tsFunc = nullptr;
329 napi_value resourceName = 0;
330
331 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
332 g_mainTid = gettid();
333
334 g_jsDataInternal.id = CALL_JS_CB_DATA_TEST_ID;
335 g_jsDataInternal.secondaryThread = (secondary ? true : false);
336 g_jsDataInternal.blockOnFull = (block ? napi_tsfn_blocking : napi_tsfn_nonblocking);
337
338 auto status = napi_create_threadsafe_function(env,
339 nullptr,
340 nullptr,
341 resourceName,
342 MAX_QUEUE_SIZE,
343 THREAD_COUNT,
344 &uvThread,
345 TsFuncFinalJoinThread,
346 &g_jsDataInternal,
347 cb,
348 &tsFunc);
349 EXPECT_EQ(status, napi_ok);
350
351 if (uv_thread_create(&uvThread, TsFuncDataSourceThreadMulti, tsFunc) != 0) {
352 HILOG_ERROR("Failed to create uv thread!");
353 }
354
355 HILOG_INFO("TsFuncThreadInternal end");
356 }
357
358 class NapiThreadsafeTest : public NativeEngineTest {
359 public:
SetUpTestCase()360 static void SetUpTestCase()
361 {
362 GTEST_LOG_(INFO) << "NapiThreadsafeTest SetUpTestCase";
363 }
364
TearDownTestCase()365 static void TearDownTestCase()
366 {
367 GTEST_LOG_(INFO) << "NapiThreadsafeTest TearDownTestCase";
368 }
369
SetUp()370 void SetUp() override {}
TearDown()371 void TearDown() override {}
372 };
373
374 /**
375 * @tc.name: ThreadsafeTest001
376 * @tc.desc: Test LoadModule Func.
377 * @tc.type: FUNC
378 * @tc.require: I5K6KF
379 */
380 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest001, testing::ext::TestSize.Level1)
381 {
382 HILOG_INFO("Threadsafe_Test_0100 start");
383 napi_env env = (napi_env)engine_;
384 napi_threadsafe_function tsFunc = nullptr;
385 napi_value resourceName = 0;
386
387 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
388 g_mainTid = gettid();
389 g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
390 g_finalData.id = FINAL_CB_DATA_TEST_ID;
391
392 auto status = napi_create_threadsafe_function(env,
393 nullptr,
394 nullptr,
395 resourceName,
396 0,
397 1,
398 &g_finalData,
399 TsFuncFinal,
400 &g_jsData,
401 TsFuncCallJs,
402 &tsFunc);
403 EXPECT_EQ(status, napi_ok);
404
405 if (uv_thread_create(&g_uvThread, TsFuncDataSourceThread, tsFunc) != 0) {
406 HILOG_ERROR("Failed to create uv thread!");
407 }
408
409 HILOG_INFO("Threadsafe_Test_0100 end");
410 }
411
412 /**
413 * @tc.name: ThreadsafeTest002
414 * @tc.desc: Test LoadModule Func.
415 * @tc.type: FUNC
416 * @tc.require: I5K6KF
417 */
418 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest002, testing::ext::TestSize.Level1)
419 {
420 HILOG_INFO("Threadsafe_Test_0200 start");
421
422 // start secondary thread, block on full
423 TsFuncThreadInternal((napi_env)engine_, TsFuncCallJsMulti, g_uvTheads2, true, true);
424
425 HILOG_INFO("Threadsafe_Test_0200 end");
426 }
427
428 /**
429 * @tc.name: ThreadsafeTest003
430 * @tc.desc: Test threadsafe Func, no js.
431 * @tc.type: FUNC
432 * @tc.require: I5K6KF
433 */
434 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest003, testing::ext::TestSize.Level1)
435 {
436 HILOG_INFO("Threadsafe_Test_0300 start");
437
438 // secondary thread, not block
439 TsFuncThreadInternal((napi_env)engine_, TsFuncCallJsMulti, g_uvTheads3, false, false);
440
441 HILOG_INFO("Threadsafe_Test_0300 end");
442 }
443
444 /**
445 * @tc.name: ThreadsafeTest004
446 * @tc.desc: Test napi_release_threadsafe_function, napi_tsfn_abort.
447 * @tc.type: FUNC
448 * @tc.require: I5K6KF
449 */
450 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest004, testing::ext::TestSize.Level1)
451 {
452 HILOG_INFO("Threadsafe_Test_0400 start");
453 napi_env env = (napi_env)engine_;
454 napi_threadsafe_function tsFunc = nullptr;
455 napi_value resourceName = 0;
456
457 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
458 g_mainTid = gettid();
459 g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
460 g_finalData.id = FINAL_CB_DATA_TEST_ID;
461
462 auto status = napi_create_threadsafe_function(env,
463 nullptr,
464 nullptr,
465 resourceName,
466 0,
467 10,
468 &g_finalData,
469 TsFuncFinalTest5,
470 &g_jsData,
471 TsFuncCallJs,
472 &tsFunc);
473 EXPECT_EQ(status, napi_ok);
474 status = napi_release_threadsafe_function(tsFunc, napi_tsfn_abort);
475 EXPECT_EQ(status, napi_ok);
476 if (uv_thread_create(&g_uvThreadTest5, TsFuncDataSourceThreadAbort, tsFunc) != 0) {
477 HILOG_ERROR("Failed to create uv thread!");
478 }
479
480 HILOG_INFO("Threadsafe_Test_0400 end");
481 }
482
483 /**
484 * @tc.name: ThreadsafeTest005
485 * @tc.desc: Test initial_thread_count not enough.
486 * @tc.type: FUNC
487 * @tc.require: I5K6KF
488 */
489 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest005, testing::ext::TestSize.Level1)
490 {
491 HILOG_INFO("Threadsafe_Test_0500 start");
492 napi_env env = (napi_env)engine_;
493 napi_threadsafe_function tsFunc = nullptr;
494 napi_value resourceName = 0;
495 callSuccessCountJS = 0;
496 callSuccessCount = 0;
497 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
498 g_mainTid = gettid();
499 g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
500 g_finalData.id = FINAL_CB_DATA_TEST_ID;
501
502 auto status = napi_create_threadsafe_function(env,
503 nullptr,
504 nullptr,
505 resourceName,
506 0,
507 2,
508 &g_finalData,
509 TsFuncFinalTotal,
510 &g_jsData,
511 TsFuncCallJsTwo,
512 &tsFunc);
513 EXPECT_EQ(status, napi_ok);
514 int threadCount = THREAD_COUNT_FOUR;
515 acquireFlag = false;
516
517 for (int i = 0; i < threadCount; i++) {
518 if (uv_thread_create(&g_uvThreadTest6, TsFuncDataSourceThreadCountTotal, tsFunc) != 0) {
519 HILOG_ERROR("Failed to create uv thread!");
520 }
521 }
522
523 usleep(200 * 1000);
524 EXPECT_EQ(callSuccessCount, SUCCESS_COUNT_JS_FOUR);
525 HILOG_INFO("Threadsafe_Test_0500 end");
526 }
527
528 /**
529 * @tc.name: ThreadsafeTest006
530 * @tc.desc: Test initial_thread_count not enough but acquire.
531 * @tc.type: FUNC
532 * @tc.require: I5K6KF
533 */
534 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest006, testing::ext::TestSize.Level1)
535 {
536 HILOG_INFO("Threadsafe_Test_0600 start");
537 napi_env env = (napi_env)engine_;
538 napi_threadsafe_function tsFunc = nullptr;
539 napi_value resourceName = 0;
540 callSuccessCount = 0;
541 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
542 g_mainTid = gettid();
543 g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
544 g_finalData.id = FINAL_CB_DATA_TEST_ID;
545
546 auto status = napi_create_threadsafe_function(env,
547 nullptr,
548 nullptr,
549 resourceName,
550 0,
551 1,
552 &g_finalData,
553 TsFuncFinalTotalFour,
554 &g_jsData,
555 TsFuncCallJsFour,
556 &tsFunc);
557 EXPECT_EQ(status, napi_ok);
558 int threadCount = THREAD_COUNT_FOUR;
559 acquireFlag = true;
560
561 for (int i = 0; i < threadCount; i++) {
562 if (uv_thread_create(&g_uvThreadTest7, TsFuncDataSourceThreadCountTotal, tsFunc) != 0) {
563 HILOG_ERROR("Failed to create uv thread!");
564 }
565 }
566
567 usleep(200 * 1000);
568 EXPECT_EQ(callSuccessCount, SUCCESS_COUNT_JS_FOUR);
569 HILOG_INFO("Threadsafe_Test_0600 end");
570 }
571
572 /**
573 * @tc.name: ThreadsafeTest007
574 * @tc.desc: Test napi_ref_threadsafe_function.
575 * @tc.type: FUNC
576 * @tc.require: I5K6KF
577 */
578 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest007, testing::ext::TestSize.Level1)
579 {
580 HILOG_INFO("Threadsafe_Test_0700 start");
581
582 napi_env env = (napi_env)engine_;
583 napi_threadsafe_function tsFunc = nullptr;
584 napi_value resourceName = 0;
585
586 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
587 g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
588 g_finalData.id = FINAL_CB_DATA_TEST_ID;
589
590 auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName,
591 0, 1, &g_finalData, TsFuncFinalTotalFour, &g_jsData, TsFuncCallJsFour, &tsFunc);
592 EXPECT_EQ(status, napi_ok);
593
594 status = napi_ref_threadsafe_function(env, tsFunc);
595 EXPECT_EQ(status, napi_ok);
596
597 HILOG_INFO("Threadsafe_Test_0700 end");
598 }
599
600 /**
601 * @tc.name: ThreadsafeTest008
602 * @tc.desc: Test napi_unref_threadsafe_function.
603 * @tc.type: FUNC
604 * @tc.require: I5K6KF
605 */
606 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest008, testing::ext::TestSize.Level1)
607 {
608 HILOG_INFO("Threadsafe_Test_0800 start");
609 napi_env env = (napi_env)engine_;
610 napi_threadsafe_function tsFunc = nullptr;
611 napi_value resourceName = 0;
612
613 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
614 g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
615 g_finalData.id = FINAL_CB_DATA_TEST_ID;
616
617 auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName,
618 0, 1, &g_finalData, TsFuncFinalTotalFour, &g_jsData, TsFuncCallJsFour, &tsFunc);
619 EXPECT_EQ(status, napi_ok);
620
621 status = napi_unref_threadsafe_function(env, tsFunc);
622 EXPECT_EQ(status, napi_ok);
623
624 HILOG_INFO("Threadsafe_Test_0800 end");
625 }
626
627 /**
628 * @tc.name: ThreadsafeTest009
629 * @tc.desc: Test napi_ref_threadsafe_function and napi_unref_threadsafe_function.
630 * @tc.type: FUNC
631 * @tc.require: I5K6KF
632 */
633 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest009, testing::ext::TestSize.Level1)
634 {
635 HILOG_INFO("Threadsafe_Test_0900 start");
636 napi_env env = (napi_env)engine_;
637 napi_threadsafe_function tsFunc = nullptr;
638 napi_value resourceName = 0;
639
640 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
641 g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
642 g_finalData.id = FINAL_CB_DATA_TEST_ID;
643
644 auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName,
645 0, 1, &g_finalData, TsFuncFinalTotalFour, &g_jsData, TsFuncCallJsFour, &tsFunc);
646 EXPECT_EQ(status, napi_ok);
647
648 status = napi_unref_threadsafe_function(env, tsFunc);
649 EXPECT_EQ(status, napi_ok);
650
651 status = napi_unref_threadsafe_function(env, tsFunc);
652 EXPECT_EQ(status, napi_ok);
653
654 HILOG_INFO("Threadsafe_Test_0900 end");
655 }
656
657 /**
658 * @tc.name: ThreadsafeTest010
659 * @tc.desc: Test napi_unref_threadsafe_function and napi_release_threadsafe_function.
660 * @tc.type: FUNC
661 * @tc.require: I5K6KF
662 */
663 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest010, testing::ext::TestSize.Level1)
664 {
665 HILOG_INFO("Threadsafe_Test_1000 start");
666 napi_env env = (napi_env)engine_;
667 napi_threadsafe_function tsFunc = nullptr;
668 napi_value resourceName = 0;
669 napi_threadsafe_function_release_mode abort = napi_tsfn_abort;
670
671 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
672 g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
673 g_finalData.id = FINAL_CB_DATA_TEST_ID;
674
675 auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName,
676 0, 1, &g_finalData, TsFuncFinalTotalFour, &g_jsData, TsFuncCallJsFour, &tsFunc);
677 EXPECT_EQ(status, napi_ok);
678
679 status = napi_unref_threadsafe_function(env, tsFunc);
680 EXPECT_EQ(status, napi_ok);
681
682 status = napi_release_threadsafe_function(tsFunc, abort);
683 EXPECT_EQ(status, napi_ok);
684
685 HILOG_INFO("Threadsafe_Test_1000 end");
686 }
687
688 /**
689 * @tc.name: ThreadsafeTest011
690 * @tc.desc: Test napi_ref_threadsafe_function and napi_release_threadsafe_function.
691 * @tc.type: FUNC
692 * @tc.require: I5K6KF
693 */
694 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest011, testing::ext::TestSize.Level1)
695 {
696 HILOG_INFO("Threadsafe_Test_1100 start");
697
698 napi_env env = (napi_env)engine_;
699 napi_threadsafe_function tsFunc = nullptr;
700 napi_value resourceName = 0;
701 napi_threadsafe_function_release_mode abort = napi_tsfn_abort;
702
703 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
704 g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
705 g_finalData.id = FINAL_CB_DATA_TEST_ID;
706
707 auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName,
708 0, 1, &g_finalData, TsFuncFinalTotalFour, &g_jsData, TsFuncCallJsFour, &tsFunc);
709 EXPECT_EQ(status, napi_ok);
710
711 status = napi_ref_threadsafe_function(env, tsFunc);
712 EXPECT_EQ(status, napi_ok);
713
714 status = napi_release_threadsafe_function(tsFunc, abort);
715 EXPECT_EQ(status, napi_ok);
716
717 HILOG_INFO("Threadsafe_Test_1100 end");
718 }