1/* 2 * Copyright (c) 2021-2024 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 <chrono> 19#include <thread> 20#include <uv.h> 21 22#include "event_runner.h" 23#include "napi/native_api.h" 24#include "napi/native_node_api.h" 25#include "securec.h" 26#include "utils/log.h" 27 28struct CallJsCbData_t { 29 int32_t id = 0; 30 bool secondaryThread = false; 31 napi_threadsafe_function_call_mode blockOnFull = napi_tsfn_nonblocking; 32}; 33 34struct FinalCbData_t { 35 int32_t id = 0; 36}; 37 38struct CallbackData { 39 napi_threadsafe_function tsfn; 40 napi_async_work work; 41 napi_task_priority priority; 42}; 43 44static constexpr int32_t SEND_DATA_TEST = 11; 45static constexpr int32_t CALL_JS_CB_DATA_TEST_ID = 101; 46static constexpr int32_t FINAL_CB_DATA_TEST_ID = 1001; 47static constexpr int32_t SEND_DATAS_LENGTH = 10; 48static constexpr int32_t THREAD_COUNT = 2; 49static constexpr int32_t THREAD_COUNT_FOUR = 4; 50static constexpr int32_t MAX_QUEUE_SIZE = 3; 51static constexpr int32_t SUCCESS_COUNT_JS_FOUR = 4; 52static constexpr int32_t CALL_THREAD_SAFE_SLEEP = 2; // 2s 53static constexpr int32_t FIRST_TASK_SLEEP = 4; // 4s 54static constexpr int32_t INVALID_NAPI_THREAD_SAFE_PRIORITY = -1; 55static constexpr int32_t ADD_FIRST_NUMBER = 1; 56static constexpr int32_t ADD_SECOND_NUMBER = 2; 57static constexpr int32_t ADD_SUMMARY_RESULT = 3; 58static constexpr int32_t ARGS_SIZE = 2; 59static constexpr int32_t FIRST_RECEIVER = 1; 60static constexpr int32_t SECOND_RECEIVER = 2; 61static constexpr int32_t THIRD_RECEIVER = 3; 62static constexpr int32_t FOURTH_RECEIVER = 4; 63static constexpr int32_t FIFTH_RECEIVER = 5; 64static constexpr int32_t DATA_LENGTH = 40; 65static constexpr int32_t THREAD_SIZE = 5; 66static constexpr int32_t FIRST_THREAD_INDEX = 0; 67static constexpr int32_t SECOND_THREAD_INDEX = 1; 68static constexpr int32_t THIRD_THREAD_INDEX = 2; 69static constexpr int32_t FOURTH_THREAD_INDEX = 3; 70static constexpr int32_t FIFTH_THREAD_INDEX = 4; 71 72static pid_t g_mainTid = 0; 73static CallJsCbData_t g_jsData; 74static CallJsCbData_t g_jsDataInternal; 75static FinalCbData_t g_finalData; 76static int32_t g_sendData = 0; 77static uv_thread_t g_uvThread; 78static uv_thread_t g_uvThreadTest5; 79static uv_thread_t g_uvThreadTest6; 80static uv_thread_t g_uvThreadTest7; 81static uv_thread_t g_uvThreadSecondary; 82static uv_thread_t g_uvTheads2; 83static uv_thread_t g_uvTheads3; 84static int32_t g_sendDatas[SEND_DATAS_LENGTH]; 85static int32_t g_callSuccessCount = 0; 86static int32_t g_callSuccessCountJS = 0; 87static int32_t g_callSuccessCountJSFour = 0; 88static int32_t g_callDepth = 4; 89bool acquireFlag = false; 90static int32_t g_receiveCnt = 0; 91static bool g_isTailA = false; 92static bool g_isTailB = false; 93 94static void TsFuncCallJs(napi_env env, napi_value tsfn_cb, void* context, void* data) 95{ 96 HILOG_INFO("TsFuncCallJs called"); 97 98 EXPECT_EQ(gettid(), g_mainTid); 99 100 // expect context equal 101 EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID); 102 103 // expect data equal 104 int* pData = (int32_t*)data; 105 EXPECT_EQ((*pData), SEND_DATA_TEST); 106} 107 108static void TsFuncCallJsWithNewCall(napi_env env, napi_value tsfn_cb, void* context, void* data) 109{ 110 HILOG_INFO("TsFuncCallJsWithNewCall called"); 111 EXPECT_EQ(gettid(), g_mainTid); 112 113 // expect context equal 114 EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID); 115 116 napi_threadsafe_function tsFunc = (napi_threadsafe_function)data; 117 118 if (g_callDepth > 0) { 119 g_callDepth--; 120 auto status = napi_call_threadsafe_function(tsFunc, data, napi_tsfn_nonblocking); 121 EXPECT_EQ(status, napi_ok); 122 } 123 if (g_callDepth == 0) { 124 auto status = napi_release_threadsafe_function(tsFunc, napi_tsfn_release); 125 EXPECT_EQ(status, napi_ok); 126 } 127} 128 129static void TsFuncCallJsTwo(napi_env env, napi_value tsfn_cb, void* context, void* data) 130{ 131 HILOG_INFO("TsFuncCallJsTwo called"); 132 TsFuncCallJs(env, tsfn_cb, context, data); 133 g_callSuccessCountJS++; 134} 135static void TsFuncCallJsFour(napi_env env, napi_value tsfn_cb, void* context, void* data) 136{ 137 HILOG_INFO("TsFuncCallJsFour called"); 138 139 TsFuncCallJs(env, tsfn_cb, context, data); 140 g_callSuccessCountJSFour++; 141} 142static void TsFuncCallJsMulti(napi_env env, 143 napi_value tsfn_cb, 144 void* context, 145 void* data) 146{ 147 HILOG_INFO("TsFuncCallJsMulti called"); 148 149 EXPECT_EQ(gettid(), g_mainTid); 150 151 // expect context equal 152 EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID); 153 154 int* pData = ((int32_t*)data); 155 156 HILOG_INFO("TsFuncCallJsMulti data %d", (*pData)); 157} 158 159static void TsFuncFinal(napi_env env, void* finalizeData, void* hint) 160{ 161 HILOG_INFO("TsFuncFinal called"); 162 163 // expect thread id equal 164 EXPECT_EQ(gettid(), g_mainTid); 165 166 // wait data source thread 167 uv_thread_join(&g_uvThread); 168 169 // expect context equal 170 EXPECT_EQ(((CallJsCbData_t*)hint)->id, CALL_JS_CB_DATA_TEST_ID); 171 172 // expect finalize data equal 173 EXPECT_EQ(((FinalCbData_t*)finalizeData)->id, FINAL_CB_DATA_TEST_ID); 174} 175static void TsFuncFinalTest5(napi_env env, void* finalizeData, void* hint) 176{ 177 HILOG_INFO("TsFuncFinalTest5 called"); 178 179 // expect thread id equal 180 EXPECT_EQ(gettid(), g_mainTid); 181 182 // wait data source thread 183 uv_thread_join(&g_uvThreadTest5); 184 185 // expect context equal 186 EXPECT_EQ(((CallJsCbData_t*)hint)->id, CALL_JS_CB_DATA_TEST_ID); 187 188 // expect finalize data equal 189 EXPECT_EQ(((FinalCbData_t*)finalizeData)->id, FINAL_CB_DATA_TEST_ID); 190} 191static void TsFuncFinalTotal(napi_env env, void* finalizeData, void* hint) 192{ 193 HILOG_INFO("TsFuncFinalTotal called"); 194 uv_thread_join(&g_uvThreadTest6); 195 // when add thread,repair g_callSuccessCountJS eq SUCCESS_COUNT_JS_TWO 196 EXPECT_EQ(g_callSuccessCountJS, SUCCESS_COUNT_JS_FOUR); 197 HILOG_INFO("TsFuncFinalTotal end"); 198} 199static void TsFuncFinalTotalFour(napi_env env, void* finalizeData, void* hint) 200{ 201 HILOG_INFO("TsFuncFinalTotalFour called"); 202 uv_thread_join(&g_uvThreadTest7); 203 EXPECT_EQ(g_callSuccessCountJSFour, SUCCESS_COUNT_JS_FOUR); 204 HILOG_INFO("TsFuncFinalTotalFour end"); 205} 206static void TsFuncFinalCallback(napi_env env, void* finalizeData, void* hint) 207{ 208 HILOG_INFO("TsFuncFinalCallback called"); 209 EXPECT_EQ(g_callSuccessCountJSFour, SUCCESS_COUNT_JS_FOUR); 210 HILOG_INFO("TsFuncFinalCallback end"); 211} 212 213static void TsFuncFinalJoinThread(napi_env env, void* data, void* hint) 214{ 215 HILOG_INFO("TsFuncFinalJoinThread called"); 216 217 uv_thread_t *uvThread = reinterpret_cast<uv_thread_t*>(data); 218 CallJsCbData_t *jsData = reinterpret_cast<CallJsCbData_t*>(hint); 219 220 uv_thread_join(uvThread); 221 222 if (jsData->secondaryThread) { 223 uv_thread_join(&g_uvThreadSecondary); 224 } 225} 226 227static void TsFuncSecondaryThread(void* data) 228{ 229 HILOG_INFO("TsFuncSecondaryThread called"); 230 231 // expect thread id not equal 232 EXPECT_NE(gettid(), g_mainTid); 233 234 napi_threadsafe_function func = (napi_threadsafe_function)data; 235 236 auto status = napi_release_threadsafe_function(func, napi_tsfn_release); 237 EXPECT_EQ(status, napi_ok); 238} 239 240static void TsFuncDataSourceThread(void* data) 241{ 242 HILOG_INFO("TsFuncDataSourceThread called"); 243 244 // expect thread id not equal 245 EXPECT_NE(gettid(), g_mainTid); 246 247 napi_threadsafe_function func = (napi_threadsafe_function)data; 248 napi_threadsafe_function_call_mode blockMode = napi_tsfn_nonblocking; 249 void* context = nullptr; 250 251 auto status = napi_get_threadsafe_function_context(func, &context); 252 EXPECT_EQ(status, napi_ok); 253 254 // expect context equal 255 EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID); 256 257 // set send data 258 g_sendData = SEND_DATA_TEST; 259 260 // As main thread has set initial_thread_count to 1 and only this one secondary thread, 261 // so no need to call `napi_acquire_threadsafe_function()`. 262 status = napi_call_threadsafe_function(func, &g_sendData, blockMode); 263 EXPECT_EQ(status, napi_ok); 264 265 status = napi_release_threadsafe_function(func, napi_tsfn_release); 266 EXPECT_EQ(status, napi_ok); 267} 268static void TsFuncDataSourceThreadAbort(void* data) 269{ 270 HILOG_INFO("TsFuncDataSourceThreadAbort 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 napi_threadsafe_function_call_mode blockMode = napi_tsfn_nonblocking; 277 void* context = nullptr; 278 279 auto status = napi_get_threadsafe_function_context(func, &context); 280 EXPECT_EQ(status, napi_ok); 281 282 // expect context equal 283 EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID); 284 285 // set send data 286 g_sendData = SEND_DATA_TEST; 287 288 status = napi_call_threadsafe_function(func, &g_sendData, blockMode); 289 EXPECT_EQ(status, napi_closing); 290} 291 292static void TsFuncDataSourceThreadCountTotal(void* data) 293{ 294 HILOG_INFO("TsFuncDataSourceThreadCountTotal called"); 295 296 // expect thread id not equal 297 EXPECT_NE(gettid(), g_mainTid); 298 299 napi_threadsafe_function func = (napi_threadsafe_function)data; 300 napi_threadsafe_function_call_mode blockMode = napi_tsfn_nonblocking; 301 void* context = nullptr; 302 303 auto status = napi_get_threadsafe_function_context(func, &context); 304 EXPECT_EQ(status, napi_ok); 305 306 // expect context equal 307 EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID); 308 // set send data 309 g_sendData = SEND_DATA_TEST; 310 if (acquireFlag) { 311 std::cout<<"acquireFlag is true"<<std::endl; 312 status = napi_acquire_threadsafe_function(func); 313 EXPECT_EQ(status, napi_ok); 314 status = napi_call_threadsafe_function(func, &g_sendData, blockMode); 315 if (status == napi_ok) { 316 g_callSuccessCount++; 317 } 318 status = napi_release_threadsafe_function(func, napi_tsfn_release); 319 } else { 320 status = napi_call_threadsafe_function(func, &g_sendData, blockMode); 321 if (status == napi_ok) { 322 g_callSuccessCount++; 323 } 324 } 325 status = napi_release_threadsafe_function(func, napi_tsfn_release); 326} 327 328static void TsFuncDataSourceThreadMulti(void* data) 329{ 330 HILOG_INFO("TsFuncDataSourceThreadMulti called"); 331 332 // expect thread id not equal 333 EXPECT_NE(gettid(), g_mainTid); 334 335 napi_threadsafe_function func = (napi_threadsafe_function)data; 336 void* context = nullptr; 337 338 auto status = napi_get_threadsafe_function_context(func, &context); 339 EXPECT_EQ(status, napi_ok); 340 CallJsCbData_t* jsData = nullptr; 341 jsData = (CallJsCbData_t*)context; 342 343 if (jsData->secondaryThread) { 344 status = napi_acquire_threadsafe_function(func); 345 EXPECT_EQ(status, napi_ok); 346 347 if (uv_thread_create(&g_uvThreadSecondary, TsFuncSecondaryThread, func) != 0) { 348 HILOG_ERROR("Failed to create uv thread!"); 349 } 350 } 351 352 bool queueClosing = false; 353 bool queueFull = false; 354 int32_t index = 0; 355 for (index = SEND_DATAS_LENGTH - 1; index > -1 && !queueClosing; index--) { 356 g_sendDatas[index] = index; 357 status = napi_call_threadsafe_function(func, &g_sendDatas[index], jsData->blockOnFull); 358 HILOG_INFO("napi_call_threadsafe_function index %d status %d", index, status); 359 360 switch (status) { 361 case napi_queue_full: 362 queueFull = true; 363 index++; 364 [[fallthrough]]; 365 case napi_ok: 366 continue; 367 case napi_closing: 368 queueClosing = true; 369 break; 370 default: 371 HILOG_ERROR("Failed to call napi_call_threadsafe_function!"); 372 } 373 } 374 375 if (!queueClosing && (napi_release_threadsafe_function(func, napi_tsfn_release) != napi_ok)) { 376 HILOG_ERROR("Failed to call napi_release_threadsafe_function!"); 377 } 378} 379 380static void TsFuncThreadInternal(napi_env env, 381 napi_threadsafe_function_call_js cb, 382 uv_thread_t& uvThread, 383 bool secondary, 384 bool block) 385{ 386 HILOG_INFO("TsFuncThreadInternal start secondary %d block %d", secondary, block); 387 388 napi_threadsafe_function tsFunc = nullptr; 389 napi_value resourceName = 0; 390 391 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName); 392 g_mainTid = gettid(); 393 394 g_jsDataInternal.id = CALL_JS_CB_DATA_TEST_ID; 395 g_jsDataInternal.secondaryThread = (secondary ? true : false); 396 g_jsDataInternal.blockOnFull = (block ? napi_tsfn_blocking : napi_tsfn_nonblocking); 397 398 auto status = napi_create_threadsafe_function(env, 399 nullptr, 400 nullptr, 401 resourceName, 402 MAX_QUEUE_SIZE, 403 THREAD_COUNT, 404 &uvThread, 405 TsFuncFinalJoinThread, 406 &g_jsDataInternal, 407 cb, 408 &tsFunc); 409 EXPECT_EQ(status, napi_ok); 410 411 if (uv_thread_create(&uvThread, TsFuncDataSourceThreadMulti, tsFunc) != 0) { 412 HILOG_ERROR("Failed to create uv thread!"); 413 } 414 415 HILOG_INFO("TsFuncThreadInternal end"); 416} 417 418static napi_value JsCallback(napi_env env, napi_callback_info info) 419{ 420 size_t agrc = ARGS_SIZE; 421 napi_value argv[ARGS_SIZE] = { nullptr }; 422 napi_get_cb_info(env, info, &agrc, argv, nullptr, nullptr); 423 424 int32_t number1 = 0; 425 napi_get_value_int32(env, argv[0], &number1); 426 427 int32_t number2 = 0; 428 napi_get_value_int32(env, argv[1], &number2); 429 430 napi_value result = nullptr; 431 napi_create_int32(env, number1 + number2, &result); 432 return result; 433} 434 435static void CallJsCallback(napi_env env, napi_value jsCb) 436{ 437 napi_value undefined; 438 napi_get_undefined(env, &undefined); 439 napi_value numberOne = nullptr; 440 napi_create_int32(env, ADD_FIRST_NUMBER, &numberOne); 441 napi_value numberTwo = nullptr; 442 napi_create_int32(env, ADD_SECOND_NUMBER, &numberTwo); 443 napi_value argv[ARGS_SIZE] = { numberOne, numberTwo }; 444 445 napi_value result = nullptr; 446 napi_call_function(env, undefined, jsCb, ARGS_SIZE, argv, &result); 447 448 int32_t res = 0; 449 napi_get_value_int32(env, result, &res); 450 EXPECT_EQ(res, ADD_SUMMARY_RESULT); 451} 452 453static void StopCurrentRunner() 454{ 455 auto runner = OHOS::AppExecFwk::EventRunner::Current(); 456 if (runner != nullptr) { 457 HILOG_INFO("Stop the current runner!"); 458 runner->Stop(); 459 } 460} 461 462static void CallJs(napi_env env, napi_value jsCb, void *context, void *data) 463{ 464 EXPECT_NE(env, nullptr); 465 466 g_receiveCnt++; 467 if (g_receiveCnt == FIRST_RECEIVER) { 468 std::this_thread::sleep_for(std::chrono::seconds(FIRST_TASK_SLEEP)); 469 return; 470 } 471 // check data string 472 char *testData = reinterpret_cast<char *>(data); 473 EXPECT_NE(testData, nullptr) << "testData is nullptr"; 474 int32_t ret = 0; 475 if (g_receiveCnt == SECOND_RECEIVER) { 476 if (!g_isTailB) { 477 ret = strcmp(testData, "hello world from B"); 478 } else { 479 ret = strcmp(testData, "hello world from A"); 480 } 481 } 482 if (g_receiveCnt == THIRD_RECEIVER) { 483 if (!g_isTailB) { 484 ret = strcmp(testData, "hello world from A"); 485 } else { 486 ret = strcmp(testData, "hello world from B"); 487 } 488 } 489 EXPECT_EQ(ret, 0); 490 491 CallJsCallback(env, jsCb); 492 if (g_receiveCnt == THIRD_RECEIVER) { 493 StopCurrentRunner(); 494 } 495} 496 497static void CallJsWithDiffPriority(napi_env env, napi_value jsCb, void *context, void *data) 498{ 499 EXPECT_NE(env, nullptr); 500 501 g_receiveCnt++; 502 if (g_receiveCnt == FIRST_RECEIVER) { 503 std::this_thread::sleep_for(std::chrono::seconds(FIRST_TASK_SLEEP)); 504 return; 505 } 506 // check data string 507 char *testData = reinterpret_cast<char *>(data); 508 EXPECT_NE(testData, nullptr) << "testData is nullptr"; 509 int32_t ret = 0; 510 if (g_receiveCnt == SECOND_RECEIVER) { 511 ret = strcmp(testData, "hello world from A"); 512 } else if (g_receiveCnt == THIRD_RECEIVER) { 513 ret = strcmp(testData, "hello world from B"); 514 } else if (g_receiveCnt == FOURTH_RECEIVER) { 515 ret = strcmp(testData, "hello world from C"); 516 } else if (g_receiveCnt == FIFTH_RECEIVER) { 517 ret = strcmp(testData, "hello world from D"); 518 } 519 EXPECT_EQ(ret, 0); 520 521 CallJsCallback(env, jsCb); 522 if (g_receiveCnt == FIFTH_RECEIVER) { 523 StopCurrentRunner(); 524 } 525} 526 527class UnitLoopHandler : public OHOS::AppExecFwk::FileDescriptorListener, 528 public std::enable_shared_from_this<UnitLoopHandler> { 529public: 530 explicit UnitLoopHandler(uv_loop_t* uvLoop) : uvLoop_(uvLoop) {} 531 void OnReadable(int32_t) override { uv_run(uvLoop_, UV_RUN_NOWAIT); } 532 void OnWritable(int32_t) override { uv_run(uvLoop_, UV_RUN_NOWAIT); } 533 534private: 535 uv_loop_t* uvLoop_ = nullptr; 536}; 537 538class NapiThreadsafeTest : public NativeEngineTest { 539public: 540 static void SetUpTestCase() 541 { 542 GTEST_LOG_(INFO) << "NapiThreadsafeTest SetUpTestCase"; 543 } 544 545 static void TearDownTestCase() 546 { 547 GTEST_LOG_(INFO) << "NapiThreadsafeTest TearDownTestCase"; 548 } 549 550 void SetUp() override { AttachEventHandler(); } 551 void TearDown() override {} 552 553 void CallThreadSafeWithSamePriorityTest(napi_task_priority priority); 554 void CallThreadSafeWithDiffPriorityTest(); 555 void CallThreadSafeWithDiffPriorityMultipleThreadTest(); 556 void AttachEventHandler(); 557}; 558 559void NapiThreadsafeTest::AttachEventHandler() 560{ 561 if (eventHandler_ != nullptr) { 562 return; 563 } 564 auto uvLoop = engine_->GetUVLoop(); 565 auto fd = uvLoop != nullptr ? uv_backend_fd(uvLoop) : -1; 566 EXPECT_GE(fd, 0); 567 uv_run(uvLoop, UV_RUN_NOWAIT); 568 auto runner = OHOS::AppExecFwk::EventRunner::Create(false); 569 EXPECT_NE(runner, nullptr); 570 eventHandler_ = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner); 571 EXPECT_NE(eventHandler_, nullptr); 572 uint32_t events = OHOS::AppExecFwk::FILE_DESCRIPTOR_INPUT_EVENT | OHOS::AppExecFwk::FILE_DESCRIPTOR_OUTPUT_EVENT; 573 eventHandler_->AddFileDescriptorListener(fd, events, std::make_shared<UnitLoopHandler>(uvLoop), "uvLoopTask"); 574 HILOG_INFO("AttachEventHandler is completed!"); 575} 576 577static void CallThreadSafeFunc(napi_threadsafe_function tsfn, napi_task_priority priority) 578{ 579 char *testData = (char *)malloc(DATA_LENGTH); 580 if (testData == nullptr) { 581 return; 582 } 583 memset_s(testData, DATA_LENGTH, 0, DATA_LENGTH); 584 if (priority == napi_priority_immediate) { 585 strcpy_s(testData, DATA_LENGTH, "hello world from A"); 586 } else if (priority == napi_priority_high) { 587 strcpy_s(testData, DATA_LENGTH, "hello world from B"); 588 } else if (priority == napi_priority_low) { 589 strcpy_s(testData, DATA_LENGTH, "hello world from C"); 590 } else if (priority == napi_priority_idle) { 591 strcpy_s(testData, DATA_LENGTH, "hello world from D"); 592 } 593 auto status = 594 napi_call_threadsafe_function_with_priority(tsfn, testData, priority, true); 595 EXPECT_EQ(status, napi_ok); 596} 597 598void NapiThreadsafeTest::CallThreadSafeWithSamePriorityTest(napi_task_priority priority) 599{ 600 napi_env env = (napi_env)engine_; 601 napi_value resourceName = 0; 602 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName); 603 CallbackData *callbackData = new CallbackData(); 604 callbackData->priority = priority; 605 napi_value testFunc = nullptr; 606 napi_create_function(env, "jsCallback", NAPI_AUTO_LENGTH, JsCallback, nullptr, &testFunc); 607 608 auto status = napi_create_threadsafe_function(env, testFunc, nullptr, resourceName, 609 0, 1, callbackData, nullptr, callbackData, CallJs, &callbackData->tsfn); 610 EXPECT_EQ(status, napi_ok); 611 612 g_receiveCnt = 0; 613 napi_create_async_work( 614 env, nullptr, resourceName, [](napi_env env, void* data) { 615 CallbackData* callbackData = (CallbackData*)data; 616 char *testDataA = (char *)malloc(DATA_LENGTH); 617 memset_s(testDataA, DATA_LENGTH, 0, DATA_LENGTH); 618 strcpy_s(testDataA, DATA_LENGTH, "hello world from A"); 619 620 char *testDataB = (char *)malloc(DATA_LENGTH); 621 memset_s(testDataB, DATA_LENGTH, 0, DATA_LENGTH); 622 strcpy_s(testDataB, DATA_LENGTH, "hello world from B"); 623 // first call function to post a sleep task, then the next execution from event queue which 624 // contains two tasks. 625 auto status = 626 napi_call_threadsafe_function_with_priority(callbackData->tsfn, testDataA, napi_priority_immediate, 627 true); 628 EXPECT_EQ(status, napi_ok); 629 std::this_thread::sleep_for(std::chrono::seconds(CALL_THREAD_SAFE_SLEEP)); 630 status = napi_call_threadsafe_function_with_priority(callbackData->tsfn, testDataA, 631 callbackData->priority, g_isTailA); 632 EXPECT_EQ(status, napi_ok); 633 status = napi_call_threadsafe_function_with_priority(callbackData->tsfn, testDataB, 634 callbackData->priority, g_isTailB); 635 EXPECT_EQ(status, napi_ok); 636 }, 637 [](napi_env env, napi_status status, void* data) { 638 CallbackData* callbackData = (CallbackData*)data; 639 napi_delete_async_work(env, callbackData->work); 640 auto status1 = napi_release_threadsafe_function(callbackData->tsfn, napi_tsfn_release); 641 EXPECT_EQ(status1, napi_ok); 642 delete callbackData; 643 }, 644 callbackData, &callbackData->work); 645 napi_queue_async_work(env, callbackData->work); 646} 647 648void NapiThreadsafeTest::CallThreadSafeWithDiffPriorityTest() 649{ 650 napi_env env = (napi_env)engine_; 651 napi_value resourceName = 0; 652 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName); 653 CallbackData *callbackData = new CallbackData(); 654 napi_value testFunc = nullptr; 655 napi_create_function(env, "jsCallback", NAPI_AUTO_LENGTH, JsCallback, nullptr, &testFunc); 656 657 auto status = napi_create_threadsafe_function(env, testFunc, nullptr, resourceName, 658 0, 1, callbackData, nullptr, callbackData, CallJsWithDiffPriority, &callbackData->tsfn); 659 EXPECT_EQ(status, napi_ok); 660 661 g_receiveCnt = 0; 662 napi_create_async_work( 663 env, nullptr, resourceName, [](napi_env env, void* data) { 664 CallbackData* callbackData = (CallbackData*)data; 665 // first call function to post a sleep task, then the next execution from event queue which 666 // contains four different priority tasks. 667 auto status = 668 napi_call_threadsafe_function_with_priority(callbackData->tsfn, nullptr, napi_priority_immediate, 669 true); 670 EXPECT_EQ(status, napi_ok); 671 std::this_thread::sleep_for(std::chrono::seconds(CALL_THREAD_SAFE_SLEEP)); 672 CallThreadSafeFunc(callbackData->tsfn, napi_priority_immediate); 673 CallThreadSafeFunc(callbackData->tsfn, napi_priority_high); 674 CallThreadSafeFunc(callbackData->tsfn, napi_priority_low); 675 CallThreadSafeFunc(callbackData->tsfn, napi_priority_idle); 676 }, 677 [](napi_env env, napi_status status, void* data) { 678 CallbackData* callbackData = (CallbackData*)data; 679 napi_delete_async_work(env, callbackData->work); 680 auto status1 = napi_release_threadsafe_function(callbackData->tsfn, napi_tsfn_release); 681 EXPECT_EQ(status1, napi_ok); 682 delete callbackData; 683 }, 684 callbackData, &callbackData->work); 685 napi_queue_async_work(env, callbackData->work); 686} 687 688void NapiThreadsafeTest::CallThreadSafeWithDiffPriorityMultipleThreadTest() 689{ 690 napi_env env = (napi_env)engine_; 691 napi_value resourceName = 0; 692 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName); 693 CallbackData *callbackData = new CallbackData(); 694 napi_value testFunc = nullptr; 695 napi_create_function(env, "jsCallback", NAPI_AUTO_LENGTH, JsCallback, nullptr, &testFunc); 696 697 auto status = napi_create_threadsafe_function(env, testFunc, nullptr, resourceName, 698 0, 1, callbackData, nullptr, callbackData, CallJsWithDiffPriority, &callbackData->tsfn); 699 EXPECT_EQ(status, napi_ok); 700 701 g_receiveCnt = 0; 702 auto runFunc = [callbackData](const napi_env &env, int32_t threadIndex) { 703 if (threadIndex == FIRST_THREAD_INDEX) { 704 auto status = 705 napi_call_threadsafe_function_with_priority(callbackData->tsfn, nullptr, napi_priority_immediate, 706 true); 707 EXPECT_EQ(status, napi_ok); 708 } else if (threadIndex == SECOND_THREAD_INDEX) { 709 CallThreadSafeFunc(callbackData->tsfn, napi_priority_immediate); 710 } else if (threadIndex == THIRD_THREAD_INDEX) { 711 CallThreadSafeFunc(callbackData->tsfn, napi_priority_high); 712 } else if (threadIndex == FOURTH_THREAD_INDEX) { 713 CallThreadSafeFunc(callbackData->tsfn, napi_priority_low); 714 } else if (threadIndex == FIFTH_THREAD_INDEX) { 715 CallThreadSafeFunc(callbackData->tsfn, napi_priority_idle); 716 } 717 }; 718 std::thread runFirstThread = std::thread(runFunc, std::ref(env), 0); 719 runFirstThread.detach(); 720 std::this_thread::sleep_for(std::chrono::seconds(CALL_THREAD_SAFE_SLEEP)); 721 for (int32_t index = 1; index < THREAD_SIZE; ++index) { 722 std::thread runThread = std::thread(runFunc, std::ref(env), index); 723 runThread.detach(); 724 } 725} 726 727/** 728 * @tc.name: ThreadsafeTest001 729 * @tc.desc: Test LoadModule Func. 730 * @tc.type: FUNC 731 * @tc.require: I5K6KF 732 */ 733HWTEST_F(NapiThreadsafeTest, ThreadsafeTest001, testing::ext::TestSize.Level1) 734{ 735 HILOG_INFO("Threadsafe_Test_0100 start"); 736 napi_env env = (napi_env)engine_; 737 napi_threadsafe_function tsFunc = nullptr; 738 napi_value resourceName = 0; 739 740 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName); 741 g_mainTid = gettid(); 742 g_jsData.id = CALL_JS_CB_DATA_TEST_ID; 743 g_finalData.id = FINAL_CB_DATA_TEST_ID; 744 745 auto status = napi_create_threadsafe_function(env, 746 nullptr, 747 nullptr, 748 resourceName, 749 0, 750 1, 751 &g_finalData, 752 TsFuncFinal, 753 &g_jsData, 754 TsFuncCallJs, 755 &tsFunc); 756 EXPECT_EQ(status, napi_ok); 757 758 if (uv_thread_create(&g_uvThread, TsFuncDataSourceThread, tsFunc) != 0) { 759 HILOG_ERROR("Failed to create uv thread!"); 760 } 761 762 HILOG_INFO("Threadsafe_Test_0100 end"); 763} 764 765/** 766 * @tc.name: ThreadsafeTest002 767 * @tc.desc: Test LoadModule Func. 768 * @tc.type: FUNC 769 * @tc.require: I5K6KF 770 */ 771HWTEST_F(NapiThreadsafeTest, ThreadsafeTest002, testing::ext::TestSize.Level1) 772{ 773 HILOG_INFO("Threadsafe_Test_0200 start"); 774 775 // start secondary thread, block on full 776 TsFuncThreadInternal((napi_env)engine_, TsFuncCallJsMulti, g_uvTheads2, true, true); 777 778 HILOG_INFO("Threadsafe_Test_0200 end"); 779} 780 781/** 782 * @tc.name: ThreadsafeTest003 783 * @tc.desc: Test threadsafe Func, no js. 784 * @tc.type: FUNC 785 * @tc.require: I5K6KF 786 */ 787HWTEST_F(NapiThreadsafeTest, ThreadsafeTest003, testing::ext::TestSize.Level1) 788{ 789 HILOG_INFO("Threadsafe_Test_0300 start"); 790 791 // secondary thread, not block 792 TsFuncThreadInternal((napi_env)engine_, TsFuncCallJsMulti, g_uvTheads3, false, false); 793 794 HILOG_INFO("Threadsafe_Test_0300 end"); 795} 796 797/** 798 * @tc.name: ThreadsafeTest004 799 * @tc.desc: Test napi_release_threadsafe_function, napi_tsfn_abort. 800 * @tc.type: FUNC 801 * @tc.require: I5K6KF 802 */ 803HWTEST_F(NapiThreadsafeTest, ThreadsafeTest004, testing::ext::TestSize.Level1) 804{ 805 HILOG_INFO("Threadsafe_Test_0400 start"); 806 napi_env env = (napi_env)engine_; 807 napi_threadsafe_function tsFunc = nullptr; 808 napi_value resourceName = 0; 809 810 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName); 811 g_mainTid = gettid(); 812 g_jsData.id = CALL_JS_CB_DATA_TEST_ID; 813 g_finalData.id = FINAL_CB_DATA_TEST_ID; 814 815 auto status = napi_create_threadsafe_function(env, 816 nullptr, 817 nullptr, 818 resourceName, 819 0, 820 10, 821 &g_finalData, 822 TsFuncFinalTest5, 823 &g_jsData, 824 TsFuncCallJs, 825 &tsFunc); 826 EXPECT_EQ(status, napi_ok); 827 status = napi_release_threadsafe_function(tsFunc, napi_tsfn_abort); 828 EXPECT_EQ(status, napi_ok); 829 if (uv_thread_create(&g_uvThreadTest5, TsFuncDataSourceThreadAbort, tsFunc) != 0) { 830 HILOG_ERROR("Failed to create uv thread!"); 831 } 832 833 HILOG_INFO("Threadsafe_Test_0400 end"); 834} 835 836/** 837 * @tc.name: ThreadsafeTest005 838 * @tc.desc: Test initial_thread_count not enough. 839 * @tc.type: FUNC 840 * @tc.require: I5K6KF 841 */ 842HWTEST_F(NapiThreadsafeTest, ThreadsafeTest005, testing::ext::TestSize.Level1) 843{ 844 HILOG_INFO("Threadsafe_Test_0500 start"); 845 napi_env env = (napi_env)engine_; 846 napi_threadsafe_function tsFunc = nullptr; 847 napi_value resourceName = 0; 848 g_callSuccessCountJS = 0; 849 g_callSuccessCount = 0; 850 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName); 851 g_mainTid = gettid(); 852 g_jsData.id = CALL_JS_CB_DATA_TEST_ID; 853 g_finalData.id = FINAL_CB_DATA_TEST_ID; 854 855 auto status = napi_create_threadsafe_function(env, 856 nullptr, 857 nullptr, 858 resourceName, 859 0, 860 2, 861 &g_finalData, 862 TsFuncFinalTotal, 863 &g_jsData, 864 TsFuncCallJsTwo, 865 &tsFunc); 866 EXPECT_EQ(status, napi_ok); 867 int threadCount = THREAD_COUNT_FOUR; 868 acquireFlag = false; 869 870 for (int i = 0; i < threadCount; i++) { 871 if (uv_thread_create(&g_uvThreadTest6, TsFuncDataSourceThreadCountTotal, tsFunc) != 0) { 872 HILOG_ERROR("Failed to create uv thread!"); 873 } 874 } 875 876 usleep(200 * 1000); 877 EXPECT_EQ(g_callSuccessCount, SUCCESS_COUNT_JS_FOUR); 878 HILOG_INFO("Threadsafe_Test_0500 end"); 879} 880 881/** 882 * @tc.name: ThreadsafeTest006 883 * @tc.desc: Test initial_thread_count not enough but acquire. 884 * @tc.type: FUNC 885 * @tc.require: I5K6KF 886 */ 887HWTEST_F(NapiThreadsafeTest, ThreadsafeTest006, testing::ext::TestSize.Level1) 888{ 889 HILOG_INFO("Threadsafe_Test_0600 start"); 890 napi_env env = (napi_env)engine_; 891 napi_threadsafe_function tsFunc = nullptr; 892 napi_value resourceName = 0; 893 g_callSuccessCount = 0; 894 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName); 895 g_mainTid = gettid(); 896 g_jsData.id = CALL_JS_CB_DATA_TEST_ID; 897 g_finalData.id = FINAL_CB_DATA_TEST_ID; 898 899 auto status = napi_create_threadsafe_function(env, 900 nullptr, 901 nullptr, 902 resourceName, 903 0, 904 1, 905 &g_finalData, 906 TsFuncFinalTotalFour, 907 &g_jsData, 908 TsFuncCallJsFour, 909 &tsFunc); 910 EXPECT_EQ(status, napi_ok); 911 int threadCount = THREAD_COUNT_FOUR; 912 acquireFlag = true; 913 914 for (int i = 0; i < threadCount; i++) { 915 if (uv_thread_create(&g_uvThreadTest7, TsFuncDataSourceThreadCountTotal, tsFunc) != 0) { 916 HILOG_ERROR("Failed to create uv thread!"); 917 } 918 } 919 920 usleep(200 * 1000); 921 EXPECT_EQ(g_callSuccessCount, SUCCESS_COUNT_JS_FOUR); 922 HILOG_INFO("Threadsafe_Test_0600 end"); 923} 924 925/** 926 * @tc.name: ThreadsafeTest007 927 * @tc.desc: Test napi_ref_threadsafe_function. 928 * @tc.type: FUNC 929 * @tc.require: I5K6KF 930 */ 931HWTEST_F(NapiThreadsafeTest, ThreadsafeTest007, testing::ext::TestSize.Level1) 932{ 933 HILOG_INFO("Threadsafe_Test_0700 start"); 934 935 napi_env env = (napi_env)engine_; 936 napi_threadsafe_function tsFunc = nullptr; 937 napi_value resourceName = 0; 938 939 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName); 940 g_jsData.id = CALL_JS_CB_DATA_TEST_ID; 941 g_finalData.id = FINAL_CB_DATA_TEST_ID; 942 943 auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName, 944 0, 1, &g_finalData, TsFuncFinalCallback, &g_jsData, TsFuncCallJsFour, &tsFunc); 945 EXPECT_EQ(status, napi_ok); 946 947 status = napi_ref_threadsafe_function(env, tsFunc); 948 EXPECT_EQ(status, napi_ok); 949 950 HILOG_INFO("Threadsafe_Test_0700 end"); 951} 952 953/** 954 * @tc.name: ThreadsafeTest008 955 * @tc.desc: Test napi_unref_threadsafe_function. 956 * @tc.type: FUNC 957 * @tc.require: I5K6KF 958 */ 959HWTEST_F(NapiThreadsafeTest, ThreadsafeTest008, testing::ext::TestSize.Level1) 960{ 961 HILOG_INFO("Threadsafe_Test_0800 start"); 962 napi_env env = (napi_env)engine_; 963 napi_threadsafe_function tsFunc = nullptr; 964 napi_value resourceName = 0; 965 966 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName); 967 g_jsData.id = CALL_JS_CB_DATA_TEST_ID; 968 g_finalData.id = FINAL_CB_DATA_TEST_ID; 969 970 auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName, 971 0, 1, &g_finalData, TsFuncFinalCallback, &g_jsData, TsFuncCallJsFour, &tsFunc); 972 EXPECT_EQ(status, napi_ok); 973 974 status = napi_unref_threadsafe_function(env, tsFunc); 975 EXPECT_EQ(status, napi_ok); 976 977 HILOG_INFO("Threadsafe_Test_0800 end"); 978} 979 980/** 981 * @tc.name: ThreadsafeTest009 982 * @tc.desc: Test napi_ref_threadsafe_function and napi_unref_threadsafe_function. 983 * @tc.type: FUNC 984 * @tc.require: I5K6KF 985 */ 986HWTEST_F(NapiThreadsafeTest, ThreadsafeTest009, testing::ext::TestSize.Level1) 987{ 988 HILOG_INFO("Threadsafe_Test_0900 start"); 989 napi_env env = (napi_env)engine_; 990 napi_threadsafe_function tsFunc = nullptr; 991 napi_value resourceName = 0; 992 993 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName); 994 g_jsData.id = CALL_JS_CB_DATA_TEST_ID; 995 g_finalData.id = FINAL_CB_DATA_TEST_ID; 996 997 auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName, 998 0, 1, &g_finalData, TsFuncFinalCallback, &g_jsData, TsFuncCallJsFour, &tsFunc); 999 EXPECT_EQ(status, napi_ok); 1000 1001 status = napi_unref_threadsafe_function(env, tsFunc); 1002 EXPECT_EQ(status, napi_ok); 1003 1004 status = napi_unref_threadsafe_function(env, tsFunc); 1005 EXPECT_EQ(status, napi_ok); 1006 1007 HILOG_INFO("Threadsafe_Test_0900 end"); 1008} 1009 1010/** 1011 * @tc.name: ThreadsafeTest010 1012 * @tc.desc: Test napi_unref_threadsafe_function and napi_release_threadsafe_function. 1013 * @tc.type: FUNC 1014 * @tc.require: I5K6KF 1015 */ 1016HWTEST_F(NapiThreadsafeTest, ThreadsafeTest010, testing::ext::TestSize.Level1) 1017{ 1018 HILOG_INFO("Threadsafe_Test_1000 start"); 1019 napi_env env = (napi_env)engine_; 1020 napi_threadsafe_function tsFunc = nullptr; 1021 napi_value resourceName = 0; 1022 napi_threadsafe_function_release_mode abort = napi_tsfn_abort; 1023 1024 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName); 1025 g_jsData.id = CALL_JS_CB_DATA_TEST_ID; 1026 g_finalData.id = FINAL_CB_DATA_TEST_ID; 1027 1028 auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName, 1029 0, 1, &g_finalData, TsFuncFinalCallback, &g_jsData, TsFuncCallJsFour, &tsFunc); 1030 EXPECT_EQ(status, napi_ok); 1031 1032 status = napi_unref_threadsafe_function(env, tsFunc); 1033 EXPECT_EQ(status, napi_ok); 1034 1035 status = napi_release_threadsafe_function(tsFunc, abort); 1036 EXPECT_EQ(status, napi_ok); 1037 1038 HILOG_INFO("Threadsafe_Test_1000 end"); 1039} 1040 1041/** 1042 * @tc.name: ThreadsafeTest011 1043 * @tc.desc: Test napi_ref_threadsafe_function and napi_release_threadsafe_function. 1044 * @tc.type: FUNC 1045 * @tc.require: I5K6KF 1046 */ 1047HWTEST_F(NapiThreadsafeTest, ThreadsafeTest011, testing::ext::TestSize.Level1) 1048{ 1049 HILOG_INFO("Threadsafe_Test_1100 start"); 1050 1051 napi_env env = (napi_env)engine_; 1052 napi_threadsafe_function tsFunc = nullptr; 1053 napi_value resourceName = 0; 1054 napi_threadsafe_function_release_mode abort = napi_tsfn_abort; 1055 1056 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName); 1057 g_jsData.id = CALL_JS_CB_DATA_TEST_ID; 1058 g_finalData.id = FINAL_CB_DATA_TEST_ID; 1059 1060 auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName, 1061 0, 1, &g_finalData, TsFuncFinalCallback, &g_jsData, TsFuncCallJsFour, &tsFunc); 1062 EXPECT_EQ(status, napi_ok); 1063 1064 status = napi_ref_threadsafe_function(env, tsFunc); 1065 EXPECT_EQ(status, napi_ok); 1066 1067 status = napi_release_threadsafe_function(tsFunc, abort); 1068 EXPECT_EQ(status, napi_ok); 1069 1070 HILOG_INFO("Threadsafe_Test_1100 end"); 1071} 1072 1073/** 1074 * @tc.name: ThreadsafeWithPriorityArgsCheckTest001 1075 * @tc.desc: Test napi_call_threadsafe_function_with_priority. 1076 * @tc.type: FUNC 1077 * @tc.require: I99QUH 1078 */ 1079HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityArgsCheckTest001, testing::ext::TestSize.Level1) 1080{ 1081 HILOG_INFO("ThreadsafeWithPriorityArgsCheckTest001 start"); 1082 auto status = 1083 napi_call_threadsafe_function_with_priority(nullptr, nullptr, napi_priority_immediate, true); 1084 EXPECT_EQ(status, napi_invalid_arg); 1085 HILOG_INFO("ThreadsafeWithPriorityArgsCheckTest001 end"); 1086} 1087 1088/** 1089 * @tc.name: ThreadsafeWithPriorityArgsCheckTest002 1090 * @tc.desc: Test napi_call_threadsafe_function_with_priority. 1091 * @tc.type: FUNC 1092 * @tc.require: I99QUH 1093 */ 1094HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityArgsCheckTest002, testing::ext::TestSize.Level1) 1095{ 1096 HILOG_INFO("ThreadsafeWithPriorityArgsCheckTest002 start"); 1097 napi_env env = (napi_env)engine_; 1098 napi_value resourceName = 0; 1099 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName); 1100 CallbackData *callbackData = new CallbackData(); 1101 auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName, 1102 0, 1, callbackData, nullptr, callbackData, CallJs, &callbackData->tsfn); 1103 EXPECT_EQ(status, napi_ok); 1104 status = 1105 napi_call_threadsafe_function_with_priority(callbackData->tsfn, nullptr, 1106 static_cast<napi_task_priority>(INVALID_NAPI_THREAD_SAFE_PRIORITY), true); 1107 delete callbackData; 1108 HILOG_INFO("ThreadsafeWithPriorityArgsCheckTest002 end"); 1109} 1110 1111/** 1112 * @tc.name: ThreadsafeWithPriorityTest001 1113 * @tc.desc: Test napi_call_threadsafe_function_with_priority. 1114 * @tc.type: FUNC 1115 * @tc.require: I99QUH 1116 */ 1117HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest001, testing::ext::TestSize.Level1) 1118{ 1119 HILOG_INFO("ThreadsafeWithPriorityTest001 start"); 1120 g_isTailA = true; 1121 g_isTailB = true; 1122 auto task = [test = this]() { 1123 test->CallThreadSafeWithSamePriorityTest(napi_priority_immediate); 1124 }; 1125 EXPECT_NE(eventHandler_, nullptr); 1126 eventHandler_->PostTask(task); 1127 auto runner = eventHandler_->GetEventRunner(); 1128 EXPECT_NE(runner, nullptr); 1129 runner->Run(); 1130 HILOG_INFO("ThreadsafeWithPriorityTest001 end"); 1131} 1132 1133/** 1134 * @tc.name: ThreadsafeWithPriorityTest002 1135 * @tc.desc: Test napi_call_threadsafe_function_with_priority. 1136 * @tc.type: FUNC 1137 * @tc.require: I99QUH 1138 */ 1139HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest002, testing::ext::TestSize.Level1) 1140{ 1141 HILOG_INFO("ThreadsafeWithPriorityTest002 start"); 1142 g_isTailA = false; 1143 g_isTailB = false; 1144 auto task = [test = this]() { 1145 test->CallThreadSafeWithSamePriorityTest(napi_priority_immediate); 1146 }; 1147 EXPECT_NE(eventHandler_, nullptr); 1148 eventHandler_->PostTask(task); 1149 auto runner = eventHandler_->GetEventRunner(); 1150 EXPECT_NE(runner, nullptr); 1151 runner->Run(); 1152 HILOG_INFO("ThreadsafeWithPriorityTest002 end"); 1153} 1154 1155/** 1156 * @tc.name: ThreadsafeWithPriorityTest003 1157 * @tc.desc: Test napi_call_threadsafe_function_with_priority. 1158 * @tc.type: FUNC 1159 * @tc.require: I99QUH 1160 */ 1161HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest003, testing::ext::TestSize.Level1) 1162{ 1163 HILOG_INFO("ThreadsafeWithPriorityTest003 start"); 1164 g_isTailA = true; 1165 g_isTailB = false; 1166 auto task = [test = this]() { 1167 test->CallThreadSafeWithSamePriorityTest(napi_priority_immediate); 1168 }; 1169 EXPECT_NE(eventHandler_, nullptr); 1170 eventHandler_->PostTask(task); 1171 auto runner = eventHandler_->GetEventRunner(); 1172 EXPECT_NE(runner, nullptr); 1173 runner->Run(); 1174 HILOG_INFO("ThreadsafeWithPriorityTest003 end"); 1175} 1176 1177/** 1178 * @tc.name: ThreadsafeWithPriorityTest004 1179 * @tc.desc: Test napi_call_threadsafe_function_with_priority. 1180 * @tc.type: FUNC 1181 * @tc.require: I99QUH 1182 */ 1183HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest004, testing::ext::TestSize.Level1) 1184{ 1185 HILOG_INFO("ThreadsafeWithPriorityTest004 start"); 1186 g_isTailA = true; 1187 g_isTailB = true; 1188 auto task = [test = this]() { 1189 test->CallThreadSafeWithSamePriorityTest(napi_priority_high); 1190 }; 1191 EXPECT_NE(eventHandler_, nullptr); 1192 eventHandler_->PostTask(task); 1193 auto runner = eventHandler_->GetEventRunner(); 1194 EXPECT_NE(runner, nullptr); 1195 runner->Run(); 1196 HILOG_INFO("ThreadsafeWithPriorityTest004 end"); 1197} 1198 1199/** 1200 * @tc.name: ThreadsafeWithPriorityTest005 1201 * @tc.desc: Test napi_call_threadsafe_function_with_priority. 1202 * @tc.type: FUNC 1203 * @tc.require: I99QUH 1204 */ 1205HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest005, testing::ext::TestSize.Level1) 1206{ 1207 HILOG_INFO("ThreadsafeWithPriorityTest005 start"); 1208 g_isTailA = false; 1209 g_isTailB = false; 1210 auto task = [test = this]() { 1211 test->CallThreadSafeWithSamePriorityTest(napi_priority_high); 1212 }; 1213 EXPECT_NE(eventHandler_, nullptr); 1214 eventHandler_->PostTask(task); 1215 auto runner = eventHandler_->GetEventRunner(); 1216 EXPECT_NE(runner, nullptr); 1217 runner->Run(); 1218 HILOG_INFO("ThreadsafeWithPriorityTest005 end"); 1219} 1220 1221/** 1222 * @tc.name: ThreadsafeWithPriorityTest006 1223 * @tc.desc: Test napi_call_threadsafe_function_with_priority. 1224 * @tc.type: FUNC 1225 * @tc.require: I99QUH 1226 */ 1227HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest006, testing::ext::TestSize.Level1) 1228{ 1229 HILOG_INFO("ThreadsafeWithPriorityTest006 start"); 1230 g_isTailA = true; 1231 g_isTailB = false; 1232 auto task = [test = this]() { 1233 test->CallThreadSafeWithSamePriorityTest(napi_priority_high); 1234 }; 1235 EXPECT_NE(eventHandler_, nullptr); 1236 eventHandler_->PostTask(task); 1237 auto runner = eventHandler_->GetEventRunner(); 1238 EXPECT_NE(runner, nullptr); 1239 runner->Run(); 1240 HILOG_INFO("ThreadsafeWithPriorityTest006 end"); 1241} 1242 1243/** 1244 * @tc.name: ThreadsafeWithPriorityTest007 1245 * @tc.desc: Test napi_call_threadsafe_function_with_priority. 1246 * @tc.type: FUNC 1247 * @tc.require: I99QUH 1248 */ 1249HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest007, testing::ext::TestSize.Level1) 1250{ 1251 HILOG_INFO("ThreadsafeWithPriorityTest007 start"); 1252 g_isTailA = true; 1253 g_isTailB = true; 1254 auto task = [test = this]() { 1255 test->CallThreadSafeWithSamePriorityTest(napi_priority_low); 1256 }; 1257 EXPECT_NE(eventHandler_, nullptr); 1258 eventHandler_->PostTask(task); 1259 auto runner = eventHandler_->GetEventRunner(); 1260 EXPECT_NE(runner, nullptr); 1261 runner->Run(); 1262 HILOG_INFO("ThreadsafeWithPriorityTest007 end"); 1263} 1264 1265/** 1266 * @tc.name: ThreadsafeWithPriorityTest008 1267 * @tc.desc: Test napi_call_threadsafe_function_with_priority. 1268 * @tc.type: FUNC 1269 * @tc.require: I99QUH 1270 */ 1271HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest008, testing::ext::TestSize.Level1) 1272{ 1273 HILOG_INFO("ThreadsafeWithPriorityTest008 start"); 1274 g_isTailA = false; 1275 g_isTailB = false; 1276 auto task = [test = this]() { 1277 test->CallThreadSafeWithSamePriorityTest(napi_priority_low); 1278 }; 1279 EXPECT_NE(eventHandler_, nullptr); 1280 eventHandler_->PostTask(task); 1281 auto runner = eventHandler_->GetEventRunner(); 1282 EXPECT_NE(runner, nullptr); 1283 runner->Run(); 1284 HILOG_INFO("ThreadsafeWithPriorityTest008 end"); 1285} 1286 1287/** 1288 * @tc.name: ThreadsafeWithPriorityTest009 1289 * @tc.desc: Test napi_call_threadsafe_function_with_priority. 1290 * @tc.type: FUNC 1291 * @tc.require: I99QUH 1292 */ 1293HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest009, testing::ext::TestSize.Level1) 1294{ 1295 HILOG_INFO("ThreadsafeWithPriorityTest009 start"); 1296 g_isTailA = true; 1297 g_isTailB = false; 1298 auto task = [test = this]() { 1299 test->CallThreadSafeWithSamePriorityTest(napi_priority_low); 1300 }; 1301 EXPECT_NE(eventHandler_, nullptr); 1302 eventHandler_->PostTask(task); 1303 auto runner = eventHandler_->GetEventRunner(); 1304 EXPECT_NE(runner, nullptr); 1305 runner->Run(); 1306 HILOG_INFO("ThreadsafeWithPriorityTest009 end"); 1307} 1308 1309 1310/** 1311 * @tc.name: ThreadsafeWithPriorityTest010 1312 * @tc.desc: Test napi_call_threadsafe_function_with_priority. 1313 * @tc.type: FUNC 1314 * @tc.require: I99QUH 1315 */ 1316HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest010, testing::ext::TestSize.Level1) 1317{ 1318 HILOG_INFO("ThreadsafeWithPriorityTest010 start"); 1319 g_isTailA = true; 1320 g_isTailB = true; 1321 auto task = [test = this]() { 1322 test->CallThreadSafeWithSamePriorityTest(napi_priority_idle); 1323 }; 1324 EXPECT_NE(eventHandler_, nullptr); 1325 eventHandler_->PostTask(task); 1326 auto runner = eventHandler_->GetEventRunner(); 1327 EXPECT_NE(runner, nullptr); 1328 runner->Run(); 1329 HILOG_INFO("ThreadsafeWithPriorityTest010 end"); 1330} 1331 1332/** 1333 * @tc.name: ThreadsafeWithPriorityTest011 1334 * @tc.desc: Test napi_call_threadsafe_function_with_priority. 1335 * @tc.type: FUNC 1336 * @tc.require: I99QUH 1337 */ 1338HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest011, testing::ext::TestSize.Level1) 1339{ 1340 HILOG_INFO("ThreadsafeWithPriorityTest005 start"); 1341 g_isTailA = false; 1342 g_isTailB = false; 1343 auto task = [test = this]() { 1344 test->CallThreadSafeWithSamePriorityTest(napi_priority_idle); 1345 }; 1346 EXPECT_NE(eventHandler_, nullptr); 1347 eventHandler_->PostTask(task); 1348 auto runner = eventHandler_->GetEventRunner(); 1349 EXPECT_NE(runner, nullptr); 1350 runner->Run(); 1351 HILOG_INFO("ThreadsafeWithPriorityTest011 end"); 1352} 1353 1354/** 1355 * @tc.name: ThreadsafeWithPriorityTest012 1356 * @tc.desc: Test napi_call_threadsafe_function_with_priority. 1357 * @tc.type: FUNC 1358 * @tc.require: I99QUH 1359 */ 1360HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest012, testing::ext::TestSize.Level1) 1361{ 1362 HILOG_INFO("ThreadsafeWithPriorityTest012 start"); 1363 g_isTailA = true; 1364 g_isTailB = false; 1365 auto task = [test = this]() { 1366 test->CallThreadSafeWithSamePriorityTest(napi_priority_idle); 1367 }; 1368 EXPECT_NE(eventHandler_, nullptr); 1369 eventHandler_->PostTask(task); 1370 auto runner = eventHandler_->GetEventRunner(); 1371 EXPECT_NE(runner, nullptr); 1372 runner->Run(); 1373 HILOG_INFO("ThreadsafeWithPriorityTest012 end"); 1374} 1375 1376/** 1377 * @tc.name: ThreadsafeWithPriorityTest013 1378 * @tc.desc: Test napi_call_threadsafe_function_with_priority. 1379 * @tc.type: FUNC 1380 * @tc.require: I99QUH 1381 */ 1382HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest013, testing::ext::TestSize.Level1) 1383{ 1384 HILOG_INFO("ThreadsafeWithPriorityTest013 start"); 1385 auto task = [test = this]() { 1386 test->CallThreadSafeWithDiffPriorityTest(); 1387 }; 1388 EXPECT_NE(eventHandler_, nullptr); 1389 eventHandler_->PostTask(task); 1390 auto runner = eventHandler_->GetEventRunner(); 1391 EXPECT_NE(runner, nullptr); 1392 runner->Run(); 1393 HILOG_INFO("ThreadsafeWithPriorityTest013 end"); 1394} 1395 1396/** 1397 * @tc.name: ThreadsafeWithPriorityTest014 1398 * @tc.desc: Test napi_call_threadsafe_function_with_priority. 1399 * @tc.type: FUNC 1400 * @tc.require: I99QUH 1401 */ 1402HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest014, testing::ext::TestSize.Level1) 1403{ 1404 HILOG_INFO("ThreadsafeWithPriorityTest014 start"); 1405 auto task = [test = this]() { 1406 test->CallThreadSafeWithDiffPriorityMultipleThreadTest(); 1407 }; 1408 EXPECT_NE(eventHandler_, nullptr); 1409 eventHandler_->PostTask(task); 1410 auto runner = eventHandler_->GetEventRunner(); 1411 EXPECT_NE(runner, nullptr); 1412 runner->Run(); 1413 HILOG_INFO("ThreadsafeWithPriorityTest014 end"); 1414} 1415 1416/** 1417 * @tc.name: ThreadsafeTest012 1418 * @tc.desc: Test LoadModule Func, call napi_call_threadsafe_function in callback. 1419 * @tc.type: FUNC 1420 * @tc.require: I5K6KF 1421 */ 1422HWTEST_F(NapiThreadsafeTest, ThreadsafeTest012, testing::ext::TestSize.Level1) 1423{ 1424 HILOG_INFO("Threadsafe_Test_1200 start"); 1425 napi_env env = (napi_env)engine_; 1426 napi_threadsafe_function tsFunc = nullptr; 1427 napi_value resourceName = 0; 1428 1429 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName); 1430 g_mainTid = gettid(); 1431 g_jsData.id = CALL_JS_CB_DATA_TEST_ID; 1432 g_finalData.id = FINAL_CB_DATA_TEST_ID; 1433 1434 auto status = napi_create_threadsafe_function(env, 1435 nullptr, 1436 nullptr, 1437 resourceName, 1438 0, 1439 1, 1440 &g_finalData, 1441 TsFuncFinal, 1442 &g_jsData, 1443 TsFuncCallJsWithNewCall, 1444 &tsFunc); 1445 EXPECT_EQ(status, napi_ok); 1446 1447 if (uv_thread_create( 1448 &g_uvThread, 1449 [](void *data) { 1450 napi_threadsafe_function func = (napi_threadsafe_function)data; 1451 auto status = napi_call_threadsafe_function(func, data, napi_tsfn_nonblocking); 1452 EXPECT_EQ(status, napi_ok); 1453 }, 1454 tsFunc) != 0) { 1455 HILOG_ERROR("Failed to create uv thread!"); 1456 } 1457 1458 HILOG_INFO("Threadsafe_Test_1200 end"); 1459}