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