14d6c458bSopenharmony_ci/* 24d6c458bSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 34d6c458bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44d6c458bSopenharmony_ci * you may not use this file except in compliance with the License. 54d6c458bSopenharmony_ci * You may obtain a copy of the License at 64d6c458bSopenharmony_ci * 74d6c458bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84d6c458bSopenharmony_ci * 94d6c458bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104d6c458bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114d6c458bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124d6c458bSopenharmony_ci * See the License for the specific language governing permissions and 134d6c458bSopenharmony_ci * limitations under the License. 144d6c458bSopenharmony_ci */ 154d6c458bSopenharmony_ci 164d6c458bSopenharmony_ci#ifndef JS_CONCURRENT_MODULE_WORKER_WORKER_H 174d6c458bSopenharmony_ci#define JS_CONCURRENT_MODULE_WORKER_WORKER_H 184d6c458bSopenharmony_ci 194d6c458bSopenharmony_ci#include <condition_variable> 204d6c458bSopenharmony_ci#include <list> 214d6c458bSopenharmony_ci#include <map> 224d6c458bSopenharmony_ci#include <mutex> 234d6c458bSopenharmony_ci 244d6c458bSopenharmony_ci#include "helper/napi_helper.h" 254d6c458bSopenharmony_ci#include "helper/object_helper.h" 264d6c458bSopenharmony_ci#include "message_queue.h" 274d6c458bSopenharmony_ci#include "napi/native_api.h" 284d6c458bSopenharmony_ci#include "napi/native_node_api.h" 294d6c458bSopenharmony_ci#include "native_engine/native_engine.h" 304d6c458bSopenharmony_ci#include "worker_runner.h" 314d6c458bSopenharmony_ci#if defined(ENABLE_WORKER_EVENTHANDLER) 324d6c458bSopenharmony_ci#include "event_handler.h" 334d6c458bSopenharmony_ci#endif 344d6c458bSopenharmony_ci 354d6c458bSopenharmony_cinamespace Commonlibrary::Concurrent::WorkerModule { 364d6c458bSopenharmony_ciusing namespace Commonlibrary::Concurrent::Common::Helper; 374d6c458bSopenharmony_ci 384d6c458bSopenharmony_ciclass Worker { 394d6c458bSopenharmony_cipublic: 404d6c458bSopenharmony_ci enum RunnerState { STARTING, RUNNING, TERMINATEING, TERMINATED }; 414d6c458bSopenharmony_ci enum HostState { ACTIVE, INACTIVE }; 424d6c458bSopenharmony_ci enum ListenerMode { ONCE, PERMANENT }; 434d6c458bSopenharmony_ci enum ScriptMode { CLASSIC, MODULE }; 444d6c458bSopenharmony_ci 454d6c458bSopenharmony_ci using DebuggerPostTask = std::function<void()>; 464d6c458bSopenharmony_ci 474d6c458bSopenharmony_ci struct WorkerListener { 484d6c458bSopenharmony_ci WorkerListener(napi_env env, napi_ref callback, ListenerMode mode) 494d6c458bSopenharmony_ci : env_(env), callback_(callback), mode_(mode) 504d6c458bSopenharmony_ci {} 514d6c458bSopenharmony_ci 524d6c458bSopenharmony_ci ~WorkerListener() 534d6c458bSopenharmony_ci { 544d6c458bSopenharmony_ci NapiHelper::DeleteReference(env_, callback_); 554d6c458bSopenharmony_ci callback_ = nullptr; 564d6c458bSopenharmony_ci } 574d6c458bSopenharmony_ci 584d6c458bSopenharmony_ci bool NextIsAvailable() const 594d6c458bSopenharmony_ci { 604d6c458bSopenharmony_ci return mode_ != ONCE; 614d6c458bSopenharmony_ci } 624d6c458bSopenharmony_ci 634d6c458bSopenharmony_ci void SetMode(ListenerMode mode) 644d6c458bSopenharmony_ci { 654d6c458bSopenharmony_ci mode_ = mode; 664d6c458bSopenharmony_ci } 674d6c458bSopenharmony_ci 684d6c458bSopenharmony_ci bool operator==(const WorkerListener& listener) const; 694d6c458bSopenharmony_ci 704d6c458bSopenharmony_ci napi_env env_ {NULL}; 714d6c458bSopenharmony_ci napi_ref callback_ {NULL}; 724d6c458bSopenharmony_ci ListenerMode mode_ {PERMANENT}; 734d6c458bSopenharmony_ci }; 744d6c458bSopenharmony_ci 754d6c458bSopenharmony_ci struct FindWorkerListener { 764d6c458bSopenharmony_ci FindWorkerListener(napi_env env, napi_ref ref) : env_(env), ref_(ref) {} 774d6c458bSopenharmony_ci 784d6c458bSopenharmony_ci bool operator()(const WorkerListener* listener) const 794d6c458bSopenharmony_ci { 804d6c458bSopenharmony_ci napi_value compareObj = NapiHelper::GetReferenceValue(env_, listener->callback_); 814d6c458bSopenharmony_ci napi_value obj = NapiHelper::GetReferenceValue(env_, ref_); 824d6c458bSopenharmony_ci // the env of listener and cmp listener must be same env because of Synchronization method 834d6c458bSopenharmony_ci return NapiHelper::StrictEqual(env_, compareObj, obj); 844d6c458bSopenharmony_ci } 854d6c458bSopenharmony_ci 864d6c458bSopenharmony_ci napi_env env_ {nullptr}; 874d6c458bSopenharmony_ci napi_ref ref_ {nullptr}; 884d6c458bSopenharmony_ci }; 894d6c458bSopenharmony_ci 904d6c458bSopenharmony_ci struct WorkerParams { 914d6c458bSopenharmony_ci std::string name_ {}; 924d6c458bSopenharmony_ci ScriptMode type_ {CLASSIC}; 934d6c458bSopenharmony_ci }; 944d6c458bSopenharmony_ci 954d6c458bSopenharmony_ci /** 964d6c458bSopenharmony_ci * Creates a worker instance. 974d6c458bSopenharmony_ci * 984d6c458bSopenharmony_ci * @param env NAPI environment parameters. 994d6c458bSopenharmony_ci * @param thisVar URL of the script to be executed by the worker. 1004d6c458bSopenharmony_ci */ 1014d6c458bSopenharmony_ci Worker(napi_env env, napi_ref thisVar); 1024d6c458bSopenharmony_ci 1034d6c458bSopenharmony_ci /** 1044d6c458bSopenharmony_ci * The destructor of the Worker. 1054d6c458bSopenharmony_ci */ 1064d6c458bSopenharmony_ci ~Worker(); 1074d6c458bSopenharmony_ci 1084d6c458bSopenharmony_ci /** 1094d6c458bSopenharmony_ci * The host thread receives the information. 1104d6c458bSopenharmony_ci * 1114d6c458bSopenharmony_ci * @param req The value of the object passed in by the js layer. 1124d6c458bSopenharmony_ci */ 1134d6c458bSopenharmony_ci static void HostOnMessage(const uv_async_t* req); 1144d6c458bSopenharmony_ci 1154d6c458bSopenharmony_ci /** 1164d6c458bSopenharmony_ci * The host thread receives the information. 1174d6c458bSopenharmony_ci * 1184d6c458bSopenharmony_ci * @param req The value of the object passed in by the js layer. 1194d6c458bSopenharmony_ci */ 1204d6c458bSopenharmony_ci static void HostOnError(const uv_async_t* req); 1214d6c458bSopenharmony_ci 1224d6c458bSopenharmony_ci /** 1234d6c458bSopenharmony_ci * The worker thread receives the information. 1244d6c458bSopenharmony_ci * 1254d6c458bSopenharmony_ci * @param req The value of the object passed in by the js layer. 1264d6c458bSopenharmony_ci */ 1274d6c458bSopenharmony_ci static void WorkerOnMessage(const uv_async_t* req); 1284d6c458bSopenharmony_ci 1294d6c458bSopenharmony_ci /** 1304d6c458bSopenharmony_ci * ExecuteIn in thread. 1314d6c458bSopenharmony_ci * 1324d6c458bSopenharmony_ci * @param data The worker pointer. 1334d6c458bSopenharmony_ci */ 1344d6c458bSopenharmony_ci static void ExecuteInThread(const void* data); 1354d6c458bSopenharmony_ci 1364d6c458bSopenharmony_ci /** 1374d6c458bSopenharmony_ci * Post a message. 1384d6c458bSopenharmony_ci * 1394d6c458bSopenharmony_ci * @param env NAPI environment parameters. 1404d6c458bSopenharmony_ci * @param thisVar The callback information of the js layer. 1414d6c458bSopenharmony_ci */ 1424d6c458bSopenharmony_ci static napi_value PostMessage(napi_env env, napi_callback_info cbinfo); 1434d6c458bSopenharmony_ci 1444d6c458bSopenharmony_ci /** 1454d6c458bSopenharmony_ci * Post a message, if has sendable objects in it pass sendable objects' reference. 1464d6c458bSopenharmony_ci * 1474d6c458bSopenharmony_ci * @param env NAPI environment parameters. 1484d6c458bSopenharmony_ci * @param thisVar The callback information of the js layer. 1494d6c458bSopenharmony_ci */ 1504d6c458bSopenharmony_ci static napi_value PostMessageWithSharedSendable(napi_env env, napi_callback_info cbinfo); 1514d6c458bSopenharmony_ci 1524d6c458bSopenharmony_ci /** 1534d6c458bSopenharmony_ci * postMessage implementation 1544d6c458bSopenharmony_ci * 1554d6c458bSopenharmony_ci * @param env NAPI environment parameters. 1564d6c458bSopenharmony_ci * @param thisVar The callback information of the js layer. 1574d6c458bSopenharmony_ci */ 1584d6c458bSopenharmony_ci static napi_value CommonPostMessage(napi_env env, napi_callback_info cbinfo, bool cloneSendable); 1594d6c458bSopenharmony_ci 1604d6c458bSopenharmony_ci /** 1614d6c458bSopenharmony_ci * Add event listeners to host. 1624d6c458bSopenharmony_ci * 1634d6c458bSopenharmony_ci * @param env NAPI environment parameters. 1644d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 1654d6c458bSopenharmony_ci */ 1664d6c458bSopenharmony_ci static napi_value PostMessageToHost(napi_env env, napi_callback_info cbinfo); 1674d6c458bSopenharmony_ci 1684d6c458bSopenharmony_ci /** 1694d6c458bSopenharmony_ci * Post a message, if has sendable objects in it pass sendable objects' reference. 1704d6c458bSopenharmony_ci * 1714d6c458bSopenharmony_ci * @param env NAPI environment parameters. 1724d6c458bSopenharmony_ci * @param thisVar The callback information of the js layer. 1734d6c458bSopenharmony_ci */ 1744d6c458bSopenharmony_ci static napi_value PostMessageWithSharedSendableToHost(napi_env env, napi_callback_info cbinfo); 1754d6c458bSopenharmony_ci 1764d6c458bSopenharmony_ci /** 1774d6c458bSopenharmony_ci * postMessage implementation 1784d6c458bSopenharmony_ci * 1794d6c458bSopenharmony_ci * @param env NAPI environment parameters. 1804d6c458bSopenharmony_ci * @param thisVar The callback information of the js layer. 1814d6c458bSopenharmony_ci */ 1824d6c458bSopenharmony_ci static napi_value CommonPostMessageToHost(napi_env env, napi_callback_info cbinfo, bool cloneSendable); 1834d6c458bSopenharmony_ci 1844d6c458bSopenharmony_ci /** 1854d6c458bSopenharmony_ci * Terminates the worker thread to stop the worker from receiving messages. 1864d6c458bSopenharmony_ci * 1874d6c458bSopenharmony_ci * @param env NAPI environment parameters. 1884d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 1894d6c458bSopenharmony_ci */ 1904d6c458bSopenharmony_ci static napi_value Terminate(napi_env env, napi_callback_info cbinfo); 1914d6c458bSopenharmony_ci 1924d6c458bSopenharmony_ci /** 1934d6c458bSopenharmony_ci * Close the worker. 1944d6c458bSopenharmony_ci * 1954d6c458bSopenharmony_ci * @param env NAPI environment parameters. 1964d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 1974d6c458bSopenharmony_ci */ 1984d6c458bSopenharmony_ci static napi_value CloseWorker(napi_env env, napi_callback_info cbinfo); 1994d6c458bSopenharmony_ci 2004d6c458bSopenharmony_ci /** 2014d6c458bSopenharmony_ci * Adds an event listener to the worker. 2024d6c458bSopenharmony_ci * 2034d6c458bSopenharmony_ci * @param env NAPI environment parameters. 2044d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 2054d6c458bSopenharmony_ci */ 2064d6c458bSopenharmony_ci static napi_value On(napi_env env, napi_callback_info cbinfo); 2074d6c458bSopenharmony_ci 2084d6c458bSopenharmony_ci /** 2094d6c458bSopenharmony_ci * Adds an event listener to the worker and removes the event listener automatically after it is invoked once. 2104d6c458bSopenharmony_ci * 2114d6c458bSopenharmony_ci * @param env NAPI environment parameters. 2124d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 2134d6c458bSopenharmony_ci */ 2144d6c458bSopenharmony_ci static napi_value Once(napi_env env, napi_callback_info cbinfo); 2154d6c458bSopenharmony_ci 2164d6c458bSopenharmony_ci /** 2174d6c458bSopenharmony_ci * Removes an event listener to the worker. 2184d6c458bSopenharmony_ci * 2194d6c458bSopenharmony_ci * @param env NAPI environment parameters. 2204d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 2214d6c458bSopenharmony_ci */ 2224d6c458bSopenharmony_ci static napi_value Off(napi_env env, napi_callback_info cbinfo); 2234d6c458bSopenharmony_ci 2244d6c458bSopenharmony_ci /** 2254d6c458bSopenharmony_ci * Add event listeners. 2264d6c458bSopenharmony_ci * 2274d6c458bSopenharmony_ci * @param env NAPI environment parameters. 2284d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 2294d6c458bSopenharmony_ci */ 2304d6c458bSopenharmony_ci static napi_value AddEventListener(napi_env env, napi_callback_info cbinfo); 2314d6c458bSopenharmony_ci 2324d6c458bSopenharmony_ci /** 2334d6c458bSopenharmony_ci * Dispatch the event. 2344d6c458bSopenharmony_ci * 2354d6c458bSopenharmony_ci * @param env NAPI environment parameters. 2364d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 2374d6c458bSopenharmony_ci */ 2384d6c458bSopenharmony_ci static napi_value DispatchEvent(napi_env env, napi_callback_info cbinfo); 2394d6c458bSopenharmony_ci 2404d6c458bSopenharmony_ci /** 2414d6c458bSopenharmony_ci * Remove the event listener. 2424d6c458bSopenharmony_ci * 2434d6c458bSopenharmony_ci * @param env NAPI environment parameters. 2444d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 2454d6c458bSopenharmony_ci */ 2464d6c458bSopenharmony_ci static napi_value RemoveEventListener(napi_env env, napi_callback_info cbinfo); 2474d6c458bSopenharmony_ci 2484d6c458bSopenharmony_ci /** 2494d6c458bSopenharmony_ci * Remove all listener. 2504d6c458bSopenharmony_ci * 2514d6c458bSopenharmony_ci * @param env NAPI environment parameters. 2524d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 2534d6c458bSopenharmony_ci */ 2544d6c458bSopenharmony_ci static napi_value RemoveAllListener(napi_env env, napi_callback_info cbinfo); 2554d6c458bSopenharmony_ci 2564d6c458bSopenharmony_ci /** 2574d6c458bSopenharmony_ci * Add the listener. 2584d6c458bSopenharmony_ci * 2594d6c458bSopenharmony_ci * @param env NAPI environment parameters. 2604d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 2614d6c458bSopenharmony_ci */ 2624d6c458bSopenharmony_ci static napi_value AddListener(napi_env env, napi_callback_info cbinfo, ListenerMode mode); 2634d6c458bSopenharmony_ci 2644d6c458bSopenharmony_ci /** 2654d6c458bSopenharmony_ci * Remove the listener. 2664d6c458bSopenharmony_ci * 2674d6c458bSopenharmony_ci * @param env NAPI environment parameters. 2684d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 2694d6c458bSopenharmony_ci */ 2704d6c458bSopenharmony_ci static napi_value RemoveListener(napi_env env, napi_callback_info cbinfo); 2714d6c458bSopenharmony_ci 2724d6c458bSopenharmony_ci /** 2734d6c458bSopenharmony_ci * The constructor of worker. 2744d6c458bSopenharmony_ci * 2754d6c458bSopenharmony_ci * @param env NAPI environment parameters. 2764d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 2774d6c458bSopenharmony_ci */ 2784d6c458bSopenharmony_ci static napi_value LimitedWorkerConstructor(napi_env env, napi_callback_info cbinfo); 2794d6c458bSopenharmony_ci static napi_value ThreadWorkerConstructor(napi_env env, napi_callback_info cbinfo); 2804d6c458bSopenharmony_ci static napi_value WorkerConstructor(napi_env env, napi_callback_info cbinfo); 2814d6c458bSopenharmony_ci static napi_value Constructor(napi_env env, napi_callback_info cbinfo, bool limitSign = false, 2824d6c458bSopenharmony_ci WorkerVersion version = WorkerVersion::NONE); 2834d6c458bSopenharmony_ci 2844d6c458bSopenharmony_ci /** 2854d6c458bSopenharmony_ci * Initialize the worker and port. 2864d6c458bSopenharmony_ci * 2874d6c458bSopenharmony_ci * @param env NAPI environment parameters. 2884d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 2894d6c458bSopenharmony_ci */ 2904d6c458bSopenharmony_ci static napi_value InitWorker(napi_env env, napi_value exports); 2914d6c458bSopenharmony_ci static napi_value InitPort(napi_env env, napi_value exports); 2924d6c458bSopenharmony_ci 2934d6c458bSopenharmony_ci /** 2944d6c458bSopenharmony_ci * Cancel the task. 2954d6c458bSopenharmony_ci * 2964d6c458bSopenharmony_ci * @param env NAPI environment parameters. 2974d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 2984d6c458bSopenharmony_ci */ 2994d6c458bSopenharmony_ci static napi_value CancelTask(napi_env env, napi_callback_info cbinfo); 3004d6c458bSopenharmony_ci 3014d6c458bSopenharmony_ci /** 3024d6c458bSopenharmony_ci * The parent port cancels the task. 3034d6c458bSopenharmony_ci * 3044d6c458bSopenharmony_ci * @param env NAPI environment parameters. 3054d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 3064d6c458bSopenharmony_ci */ 3074d6c458bSopenharmony_ci static napi_value ParentPortCancelTask(napi_env env, napi_callback_info cbinfo); 3084d6c458bSopenharmony_ci 3094d6c458bSopenharmony_ci /** 3104d6c458bSopenharmony_ci * The parent port adds an event listener. 3114d6c458bSopenharmony_ci * 3124d6c458bSopenharmony_ci * @param env NAPI environment parameters. 3134d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 3144d6c458bSopenharmony_ci */ 3154d6c458bSopenharmony_ci static napi_value ParentPortAddEventListener(napi_env env, napi_callback_info cbinfo); 3164d6c458bSopenharmony_ci 3174d6c458bSopenharmony_ci /** 3184d6c458bSopenharmony_ci * The parent port removes all event listener. 3194d6c458bSopenharmony_ci * 3204d6c458bSopenharmony_ci * @param env NAPI environment parameters. 3214d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 3224d6c458bSopenharmony_ci */ 3234d6c458bSopenharmony_ci static napi_value ParentPortRemoveAllListener(napi_env env, napi_callback_info cbinfo); 3244d6c458bSopenharmony_ci 3254d6c458bSopenharmony_ci /** 3264d6c458bSopenharmony_ci * The parent port dispatch the event listener. 3274d6c458bSopenharmony_ci * 3284d6c458bSopenharmony_ci * @param env NAPI environment parameters. 3294d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 3304d6c458bSopenharmony_ci */ 3314d6c458bSopenharmony_ci static napi_value ParentPortDispatchEvent(napi_env env, napi_callback_info cbinfo); 3324d6c458bSopenharmony_ci 3334d6c458bSopenharmony_ci /** 3344d6c458bSopenharmony_ci * The parent port removes the event listener. 3354d6c458bSopenharmony_ci * 3364d6c458bSopenharmony_ci * @param env NAPI environment parameters. 3374d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 3384d6c458bSopenharmony_ci */ 3394d6c458bSopenharmony_ci static napi_value ParentPortRemoveEventListener(napi_env env, napi_callback_info cbinfo); 3404d6c458bSopenharmony_ci 3414d6c458bSopenharmony_ci /** 3424d6c458bSopenharmony_ci * Register a globalCallObject on host side. 3434d6c458bSopenharmony_ci * 3444d6c458bSopenharmony_ci * @param env NAPI environment parameters. 3454d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 3464d6c458bSopenharmony_ci */ 3474d6c458bSopenharmony_ci static napi_value RegisterGlobalCallObject(napi_env env, napi_callback_info cbinfo); 3484d6c458bSopenharmony_ci 3494d6c458bSopenharmony_ci /** 3504d6c458bSopenharmony_ci * Unregister the specific globalCallObject on host side. 3514d6c458bSopenharmony_ci * 3524d6c458bSopenharmony_ci * @param env NAPI environment parameters. 3534d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 3544d6c458bSopenharmony_ci */ 3554d6c458bSopenharmony_ci static napi_value UnregisterGlobalCallObject(napi_env env, napi_callback_info cbinfo); 3564d6c458bSopenharmony_ci 3574d6c458bSopenharmony_ci /** 3584d6c458bSopenharmony_ci * Post a global synchronized call request to an object registered on host side. 3594d6c458bSopenharmony_ci * 3604d6c458bSopenharmony_ci * @param env NAPI environment parameters. 3614d6c458bSopenharmony_ci * @param cbinfo The callback information of the js layer. 3624d6c458bSopenharmony_ci */ 3634d6c458bSopenharmony_ci static napi_value GlobalCall(napi_env env, napi_callback_info cbinfo); 3644d6c458bSopenharmony_ci 3654d6c458bSopenharmony_ci static void HostOnGlobalCall(const uv_async_t* req); 3664d6c458bSopenharmony_ci 3674d6c458bSopenharmony_ci static bool CanCreateWorker(napi_env env, WorkerVersion target); 3684d6c458bSopenharmony_ci 3694d6c458bSopenharmony_ci static WorkerParams* CheckWorkerArgs(napi_env env, napi_value argsValue); 3704d6c458bSopenharmony_ci 3714d6c458bSopenharmony_ci static void WorkerThrowError(napi_env env, int32_t errCode, const char* errMessage = nullptr); 3724d6c458bSopenharmony_ci 3734d6c458bSopenharmony_ci static void WorkerDestructor(napi_env env, void *data, void *hint); 3744d6c458bSopenharmony_ci static void HostEnvCleanCallback(void *data); 3754d6c458bSopenharmony_ci 3764d6c458bSopenharmony_ci#if defined(ENABLE_WORKER_EVENTHANDLER) 3774d6c458bSopenharmony_ci static std::shared_ptr<OHOS::AppExecFwk::EventHandler> GetMainThreadHandler(); 3784d6c458bSopenharmony_ci#endif 3794d6c458bSopenharmony_ci 3804d6c458bSopenharmony_ci void StartExecuteInThread(napi_env env, const char* script); 3814d6c458bSopenharmony_ci 3824d6c458bSopenharmony_ci bool UpdateWorkerState(RunnerState state); 3834d6c458bSopenharmony_ci bool UpdateHostState(HostState state); 3844d6c458bSopenharmony_ci 3854d6c458bSopenharmony_ci bool IsNotTerminate() const 3864d6c458bSopenharmony_ci { 3874d6c458bSopenharmony_ci return runnerState_.load(std::memory_order_acquire) <= RUNNING; 3884d6c458bSopenharmony_ci } 3894d6c458bSopenharmony_ci 3904d6c458bSopenharmony_ci bool IsRunning() const 3914d6c458bSopenharmony_ci { 3924d6c458bSopenharmony_ci return runnerState_.load(std::memory_order_acquire) == RUNNING; 3934d6c458bSopenharmony_ci } 3944d6c458bSopenharmony_ci 3954d6c458bSopenharmony_ci bool IsTerminated() const 3964d6c458bSopenharmony_ci { 3974d6c458bSopenharmony_ci return runnerState_.load(std::memory_order_acquire) >= TERMINATED; 3984d6c458bSopenharmony_ci } 3994d6c458bSopenharmony_ci 4004d6c458bSopenharmony_ci bool IsTerminating() const 4014d6c458bSopenharmony_ci { 4024d6c458bSopenharmony_ci return runnerState_.load(std::memory_order_acquire) == TERMINATEING; 4034d6c458bSopenharmony_ci } 4044d6c458bSopenharmony_ci 4054d6c458bSopenharmony_ci void SetScriptMode(ScriptMode mode) 4064d6c458bSopenharmony_ci { 4074d6c458bSopenharmony_ci scriptMode_ = mode; 4084d6c458bSopenharmony_ci } 4094d6c458bSopenharmony_ci 4104d6c458bSopenharmony_ci void AddListenerInner(napi_env env, const char* type, const WorkerListener* listener); 4114d6c458bSopenharmony_ci void RemoveListenerInner(napi_env env, const char* type, napi_ref callback); 4124d6c458bSopenharmony_ci void RemoveAllListenerInner(); 4134d6c458bSopenharmony_ci void EraseWorker(); 4144d6c458bSopenharmony_ci uv_loop_t* GetWorkerLoop() const 4154d6c458bSopenharmony_ci { 4164d6c458bSopenharmony_ci if (workerEnv_ != nullptr) { 4174d6c458bSopenharmony_ci return NapiHelper::GetLibUV(workerEnv_); 4184d6c458bSopenharmony_ci } 4194d6c458bSopenharmony_ci return nullptr; 4204d6c458bSopenharmony_ci } 4214d6c458bSopenharmony_ci 4224d6c458bSopenharmony_ci void SetWorkerEnv(napi_env workerEnv) 4234d6c458bSopenharmony_ci { 4244d6c458bSopenharmony_ci workerEnv_ = workerEnv; 4254d6c458bSopenharmony_ci if (workerEnvCallback_) { 4264d6c458bSopenharmony_ci workerEnvCallback_(workerEnv_); 4274d6c458bSopenharmony_ci } 4284d6c458bSopenharmony_ci } 4294d6c458bSopenharmony_ci 4304d6c458bSopenharmony_ci std::string GetScript() const 4314d6c458bSopenharmony_ci { 4324d6c458bSopenharmony_ci return script_; 4334d6c458bSopenharmony_ci } 4344d6c458bSopenharmony_ci 4354d6c458bSopenharmony_ci std::string GetName() const 4364d6c458bSopenharmony_ci { 4374d6c458bSopenharmony_ci return name_; 4384d6c458bSopenharmony_ci } 4394d6c458bSopenharmony_ci 4404d6c458bSopenharmony_ci bool ClearWorkerTasks() 4414d6c458bSopenharmony_ci { 4424d6c458bSopenharmony_ci if (hostEnv_ != nullptr) { 4434d6c458bSopenharmony_ci workerMessageQueue_.Clear(hostEnv_); 4444d6c458bSopenharmony_ci return true; 4454d6c458bSopenharmony_ci } 4464d6c458bSopenharmony_ci return false; 4474d6c458bSopenharmony_ci } 4484d6c458bSopenharmony_ci 4494d6c458bSopenharmony_ci bool HostIsStop() const 4504d6c458bSopenharmony_ci { 4514d6c458bSopenharmony_ci return hostState_.load(std::memory_order_acquire) == INACTIVE; 4524d6c458bSopenharmony_ci } 4534d6c458bSopenharmony_ci 4544d6c458bSopenharmony_ci bool IsSameWorkerEnv(napi_env env) const 4554d6c458bSopenharmony_ci { 4564d6c458bSopenharmony_ci return workerEnv_ == env; 4574d6c458bSopenharmony_ci } 4584d6c458bSopenharmony_ci 4594d6c458bSopenharmony_ci void Loop() const 4604d6c458bSopenharmony_ci { 4614d6c458bSopenharmony_ci uv_loop_t* loop = GetWorkerLoop(); 4624d6c458bSopenharmony_ci if (loop != nullptr) { 4634d6c458bSopenharmony_ci uv_run(loop, UV_RUN_DEFAULT); 4644d6c458bSopenharmony_ci } else { 4654d6c458bSopenharmony_ci return; 4664d6c458bSopenharmony_ci } 4674d6c458bSopenharmony_ci } 4684d6c458bSopenharmony_ci 4694d6c458bSopenharmony_ci void RegisterCallbackForWorkerEnv(std::function<void (napi_env)> callback) 4704d6c458bSopenharmony_ci { 4714d6c458bSopenharmony_ci workerEnvCallback_ = callback; 4724d6c458bSopenharmony_ci if (workerEnv_ != nullptr) { 4734d6c458bSopenharmony_ci workerEnvCallback_(workerEnv_); 4744d6c458bSopenharmony_ci } 4754d6c458bSopenharmony_ci } 4764d6c458bSopenharmony_ci 4774d6c458bSopenharmony_ci napi_env GetWorkerEnv() const 4784d6c458bSopenharmony_ci { 4794d6c458bSopenharmony_ci return workerEnv_; 4804d6c458bSopenharmony_ci } 4814d6c458bSopenharmony_ci 4824d6c458bSopenharmony_ci napi_env GetHostEnv() const 4834d6c458bSopenharmony_ci { 4844d6c458bSopenharmony_ci return hostEnv_; 4854d6c458bSopenharmony_ci } 4864d6c458bSopenharmony_ci 4874d6c458bSopenharmony_ciprivate: 4884d6c458bSopenharmony_ci void WorkerOnMessageInner(); 4894d6c458bSopenharmony_ci void HostOnMessageInner(); 4904d6c458bSopenharmony_ci void HostOnErrorInner(); 4914d6c458bSopenharmony_ci void HostOnMessageErrorInner(); 4924d6c458bSopenharmony_ci void HostOnGlobalCallInner(); 4934d6c458bSopenharmony_ci void WorkerOnMessageErrorInner(); 4944d6c458bSopenharmony_ci void WorkerOnErrorInner(napi_value error); 4954d6c458bSopenharmony_ci 4964d6c458bSopenharmony_ci void HandleHostException() const; 4974d6c458bSopenharmony_ci void HandleException(); 4984d6c458bSopenharmony_ci void HandleUncaughtException(napi_value exception); 4994d6c458bSopenharmony_ci bool CallWorkerFunction(size_t argc, const napi_value* argv, const char* methodName, bool tryCatch); 5004d6c458bSopenharmony_ci void CallHostFunction(size_t argc, const napi_value* argv, const char* methodName) const; 5014d6c458bSopenharmony_ci 5024d6c458bSopenharmony_ci bool HandleEventListeners(napi_env env, napi_value recv, size_t argc, const napi_value* argv, const char* type); 5034d6c458bSopenharmony_ci void ParentPortHandleEventListeners(napi_env env, napi_value recv, size_t argc, 5044d6c458bSopenharmony_ci const napi_value* argv, const char* type, bool tryCatch); 5054d6c458bSopenharmony_ci void TerminateInner(); 5064d6c458bSopenharmony_ci 5074d6c458bSopenharmony_ci void PostMessageInner(MessageDataType data); 5084d6c458bSopenharmony_ci void PostMessageToHostInner(MessageDataType data); 5094d6c458bSopenharmony_ci 5104d6c458bSopenharmony_ci void TerminateWorker(); 5114d6c458bSopenharmony_ci 5124d6c458bSopenharmony_ci void CloseInner(); 5134d6c458bSopenharmony_ci 5144d6c458bSopenharmony_ci void PublishWorkerOverSignal(); 5154d6c458bSopenharmony_ci void CloseWorkerCallback(); 5164d6c458bSopenharmony_ci void CloseHostCallback(); 5174d6c458bSopenharmony_ci 5184d6c458bSopenharmony_ci void PostWorkerOverTask(); 5194d6c458bSopenharmony_ci void PostWorkerErrorTask(); 5204d6c458bSopenharmony_ci void PostWorkerMessageTask(); 5214d6c458bSopenharmony_ci void PostWorkerGlobalCallTask(); 5224d6c458bSopenharmony_ci static bool IsValidWorker(Worker* worker); 5234d6c458bSopenharmony_ci 5244d6c458bSopenharmony_ci void InitHostHandle(uv_loop_t* loop); 5254d6c458bSopenharmony_ci void CloseHostHandle(); 5264d6c458bSopenharmony_ci 5274d6c458bSopenharmony_ci void ReleaseWorkerThreadContent(); 5284d6c458bSopenharmony_ci void ReleaseHostThreadContent(); 5294d6c458bSopenharmony_ci bool PrepareForWorkerInstance(); 5304d6c458bSopenharmony_ci void ParentPortAddListenerInner(napi_env env, const char* type, const WorkerListener* listener); 5314d6c458bSopenharmony_ci void ParentPortRemoveAllListenerInner(); 5324d6c458bSopenharmony_ci void ParentPortRemoveListenerInner(napi_env env, const char* type, napi_ref callback); 5334d6c458bSopenharmony_ci void GetContainerScopeId(napi_env env); 5344d6c458bSopenharmony_ci 5354d6c458bSopenharmony_ci void AddGlobalCallObject(const std::string &instanceName, napi_ref obj); 5364d6c458bSopenharmony_ci bool RemoveGlobalCallObject(const std::string &instanceName); 5374d6c458bSopenharmony_ci void ClearGlobalCallObject(); 5384d6c458bSopenharmony_ci void AddGlobalCallError(int32_t errCode, napi_value errData = nullptr); 5394d6c458bSopenharmony_ci void HandleGlobalCallError(napi_env env); 5404d6c458bSopenharmony_ci void ClearGlobalCallError(napi_env env); 5414d6c458bSopenharmony_ci void InitGlobalCallStatus(napi_env env); 5424d6c458bSopenharmony_ci void IncreaseGlobalCallId(); 5434d6c458bSopenharmony_ci 5444d6c458bSopenharmony_ci void ClearHostMessage(napi_env env); 5454d6c458bSopenharmony_ci 5464d6c458bSopenharmony_ci#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) 5474d6c458bSopenharmony_ci static void HandleDebuggerTask(const uv_async_t* req); 5484d6c458bSopenharmony_ci void DebuggerOnPostTask(std::function<void()>&& task); 5494d6c458bSopenharmony_ci#endif 5504d6c458bSopenharmony_ci 5514d6c458bSopenharmony_ci std::string script_ {}; 5524d6c458bSopenharmony_ci std::string fileName_ {}; 5534d6c458bSopenharmony_ci std::string name_ {}; 5544d6c458bSopenharmony_ci ScriptMode scriptMode_ {CLASSIC}; 5554d6c458bSopenharmony_ci bool isLimitedWorker_ {false}; 5564d6c458bSopenharmony_ci bool isRelativePath_ {false}; 5574d6c458bSopenharmony_ci int32_t scopeId_ {-1}; 5584d6c458bSopenharmony_ci 5594d6c458bSopenharmony_ci MessageQueue workerMessageQueue_ {}; 5604d6c458bSopenharmony_ci MessageQueue hostMessageQueue_ {}; 5614d6c458bSopenharmony_ci std::mutex globalCallMutex_; 5624d6c458bSopenharmony_ci MarkedMessageQueue hostGlobalCallQueue_ {}; 5634d6c458bSopenharmony_ci MessageQueue workerGlobalCallQueue_ {}; 5644d6c458bSopenharmony_ci MessageQueue errorQueue_ {}; 5654d6c458bSopenharmony_ci 5664d6c458bSopenharmony_ci uv_async_t* workerOnMessageSignal_ = nullptr; 5674d6c458bSopenharmony_ci uv_async_t* hostOnMessageSignal_ = nullptr; 5684d6c458bSopenharmony_ci uv_async_t* hostOnErrorSignal_ = nullptr; 5694d6c458bSopenharmony_ci uv_async_t* hostOnGlobalCallSignal_ = nullptr; 5704d6c458bSopenharmony_ci#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) 5714d6c458bSopenharmony_ci uv_async_t debuggerOnPostTaskSignal_ {}; 5724d6c458bSopenharmony_ci std::mutex debuggerMutex_; 5734d6c458bSopenharmony_ci std::queue<DebuggerPostTask> debuggerQueue_ {}; 5744d6c458bSopenharmony_ci#endif 5754d6c458bSopenharmony_ci 5764d6c458bSopenharmony_ci std::atomic<RunnerState> runnerState_ {STARTING}; 5774d6c458bSopenharmony_ci std::atomic<HostState> hostState_ {ACTIVE}; 5784d6c458bSopenharmony_ci std::unique_ptr<WorkerRunner> runner_ {}; 5794d6c458bSopenharmony_ci 5804d6c458bSopenharmony_ci std::atomic<bool> isErrorExit_ = false; 5814d6c458bSopenharmony_ci 5824d6c458bSopenharmony_ci napi_env hostEnv_ {nullptr}; 5834d6c458bSopenharmony_ci napi_env workerEnv_ {nullptr}; 5844d6c458bSopenharmony_ci 5854d6c458bSopenharmony_ci napi_ref workerRef_ {nullptr}; 5864d6c458bSopenharmony_ci napi_ref workerPort_ {nullptr}; 5874d6c458bSopenharmony_ci 5884d6c458bSopenharmony_ci std::map<std::string, std::list<WorkerListener*>> eventListeners_ {}; 5894d6c458bSopenharmony_ci std::map<std::string, std::list<WorkerListener*>> parentPortEventListeners_ {}; 5904d6c458bSopenharmony_ci std::unordered_map<std::string, napi_ref> globalCallObjects_ {}; 5914d6c458bSopenharmony_ci std::queue<std::pair<int32_t, napi_value>> globalCallErrors_ {}; 5924d6c458bSopenharmony_ci std::atomic<uint32_t> globalCallId_ = 1; // 0: reserved for error check 5934d6c458bSopenharmony_ci 5944d6c458bSopenharmony_ci std::recursive_mutex liveStatusLock_ {}; 5954d6c458bSopenharmony_ci std::mutex workerOnmessageMutex_ {}; 5964d6c458bSopenharmony_ci 5974d6c458bSopenharmony_ci std::condition_variable cv_; 5984d6c458bSopenharmony_ci std::atomic<bool> globalCallSuccess_ = true; 5994d6c458bSopenharmony_ci std::function<void(napi_env)> workerEnvCallback_; 6004d6c458bSopenharmony_ci 6014d6c458bSopenharmony_ci bool isMainThreadWorker_ = true; 6024d6c458bSopenharmony_ci bool isNewVersion_ = true; 6034d6c458bSopenharmony_ci std::atomic<bool> isTerminated_ = false; 6044d6c458bSopenharmony_ci std::atomic<bool> isHostEnvExited_ = false; 6054d6c458bSopenharmony_ci 6064d6c458bSopenharmony_ci friend class WorkersTest; 6074d6c458bSopenharmony_ci}; 6084d6c458bSopenharmony_ci} // namespace Commonlibrary::Concurrent::WorkerModule 6094d6c458bSopenharmony_ci#endif // JS_CONCURRENT_MODULE_WORKER_WORKER_H 610