1/*
2 * Copyright (c) 2021 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#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_SAFE_ASYNC_WORK_H
17#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_SAFE_ASYNC_WORK_H
18
19#include "native_value.h"
20
21#include <mutex>
22#include <queue>
23#include <uv.h>
24#ifdef LINUX_PLATFORM
25#include <condition_variable>
26#endif
27
28#include "native_async_context.h"
29
30#if defined(ENABLE_EVENT_HANDLER)
31namespace OHOS::AppExecFwk {
32    class EventHandler;
33}
34#endif
35
36enum class SafeAsyncCode {
37    UNKNOWN = 0,
38    SAFE_ASYNC_QUEUE_FULL,
39    SAFE_ASYNC_INVALID_ARGS,
40    SAFE_ASYNC_CLOSED,
41    SAFE_ASYNC_FAILED,
42    SAFE_ASYNC_OK,
43};
44
45enum class SafeAsyncStatus {
46    UNKNOW = 0,
47    SAFE_ASYNC_STATUS_INTE,
48    SAFE_ASYNC_STATUS_CLOSING,
49    SAFE_ASYNC_STATUS_CLOSED,
50};
51
52typedef struct CallbackWrapper_ {
53    std::function<void()> cb;
54} CallbackWrapper;
55
56class NativeSafeAsyncWork {
57public:
58    static void AsyncCallback(uv_async_t* asyncHandler);
59    static void CallJs(NativeEngine* engine, napi_value js_call_func, void* context, void* data);
60
61    NativeSafeAsyncWork(NativeEngine* engine,
62                        napi_value func,
63                        napi_value asyncResource,
64                        napi_value asyncResourceName,
65                        size_t maxQueueSize,
66                        size_t threadCount,
67                        void* finalizeData,
68                        NativeFinalize finalizeCallback,
69                        void* context,
70                        NativeThreadSafeFunctionCallJs callJsCallback);
71
72    virtual ~NativeSafeAsyncWork();
73    virtual bool Init();
74    virtual SafeAsyncCode Send(void* data, NativeThreadSafeFunctionCallMode mode);
75    virtual SafeAsyncCode Acquire();
76    virtual SafeAsyncCode Release(NativeThreadSafeFunctionReleaseMode mode);
77    virtual bool Ref();
78    virtual bool Unref();
79    virtual void* GetContext();
80    virtual napi_status PostTask(void *data, int32_t priority, bool isTail);
81    virtual napi_status SendEvent(const std::function<void()> &cb, napi_event_priority priority);
82
83private:
84    void ProcessAsyncHandle();
85    SafeAsyncCode CloseHandles();
86    void CleanUp();
87    bool IsSameTid();
88    bool IsMaxQueueSize();
89
90    SafeAsyncCode ValidEngineCheck();
91
92    NativeEngine* engine_ = nullptr;
93    uint64_t engineId_ = 0;
94    NativeReference* ref_ = nullptr;
95    size_t maxQueueSize_ = 0;
96    size_t threadCount_ = 0;
97    void* finalizeData_ = nullptr;
98    NativeFinalize finalizeCallback_ = nullptr;
99    void* context_ = nullptr;
100    NativeThreadSafeFunctionCallJs callJsCallback_ = nullptr;
101    NativeAsyncContext asyncContext_;
102    uv_async_t asyncHandler_;
103    std::mutex mutex_;
104    std::queue<void*> queue_;
105    std::condition_variable condition_;
106    SafeAsyncStatus status_ = SafeAsyncStatus::UNKNOW;
107#if defined(ENABLE_EVENT_HANDLER)
108    std::mutex eventHandlerMutex_;
109    std::shared_ptr<OHOS::AppExecFwk::EventHandler> eventHandler_ = nullptr;
110#endif
111
112#ifdef ENABLE_CONTAINER_SCOPE
113    int32_t containerScopeId_;
114#endif
115};
116
117#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_SAFE_ASYNC_WORK_H */
118