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