• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef ASYN_CALL_H
16 #define ASYN_CALL_H
17 
18 #include "cpp/mutex.h"
19 #include "global.h"
20 #include "js_utils.h"
21 #include "ffrt.h"
22 #include "napi/native_api.h"
23 #include "napi/native_common.h"
24 #include "napi/native_node_api.h"
25 #include "event_handler.h"
26 
27 namespace OHOS {
28 namespace MiscServices {
29 class AsyncCall {
30 public:
31     class Context {
32     public:
33         using InputAction = std::function<napi_status(napi_env, size_t, napi_value *, napi_value)>;
34         using OutputAction = std::function<napi_status(napi_env, napi_value *)>;
35         using ExecAction = std::function<void(Context *)>;
36         using CallBackAction = std::function<void()>;
37         using AsynExecAction = std::function<void(Context *, CallBackAction)>;
Context(InputAction input,OutputAction output)38         Context(InputAction input, OutputAction output) : input_(std::move(input)), output_(std::move(output))
39         {
40             handler_ = AppExecFwk::EventHandler::Current();
41         };
~Context()42         virtual ~Context(){};
43         void SetAction(InputAction input, OutputAction output = nullptr)
44         {
45             input_ = input;
46             output_ = output;
47         }
48 
SetErrorCode(int32_t errorCode)49         void SetErrorCode(int32_t errorCode)
50         {
51             errorCode_ = errorCode;
52         }
53 
SetErrorMessage(const std::string & errMessage)54         void SetErrorMessage(const std::string &errMessage)
55         {
56             errMessage_ = errMessage;
57         }
58 
SetState(const napi_status & status)59         void SetState(const napi_status &status)
60         {
61             status_ = status;
62         }
63 
GetState()64         napi_status GetState()
65         {
66             return status_;
67         }
68 
SetAction(OutputAction output)69         void SetAction(OutputAction output)
70         {
71             SetAction(nullptr, std::move(output));
72         }
73 
operator()74         virtual napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self)
75         {
76             if (input_ == nullptr) {
77                 return napi_ok;
78             }
79             auto ret = input_(env, argc, argv, self);
80             input_ = nullptr;
81             return ret;
82         }
83 
operator()84         virtual napi_status operator()(napi_env env, napi_value *result)
85         {
86             if (output_ == nullptr) {
87                 *result = nullptr;
88                 return napi_ok;
89             }
90             auto ret = output_(env, result);
91             output_ = nullptr;
92             return ret;
93         }
94 
Exec()95         virtual void Exec()
96         {
97             if (exec_ == nullptr) {
98                 return;
99             }
100             exec_(this);
101             exec_ = nullptr;
102         };
103 
AsyncExec(CallBackAction cb)104         virtual void AsyncExec(CallBackAction cb)
105         {
106             if (asyncExec_ == nullptr) {
107                 return;
108             }
109             asyncExec_(this, cb);
110             asyncExec_ = nullptr;
111         };
112 
GetHandler()113         std::shared_ptr<AppExecFwk::EventHandler> GetHandler()
114         {
115             return handler_;
116         }
117     protected:
118         friend class AsyncCall;
119         InputAction input_ = nullptr;
120         OutputAction output_ = nullptr;
121         ExecAction exec_ = nullptr;
122         AsynExecAction asyncExec_ = nullptr;
123         napi_status status_ = napi_generic_failure;
124         int32_t errorCode_ = 0;
125         std::string errMessage_;
126         std::shared_ptr<AppExecFwk::EventHandler> handler_ = nullptr;
127     };
128 
129     struct InnerTask {
130         InnerTask(napi_env env, napi_async_work work, const char *name);
131         ~InnerTask();
132         napi_env env = nullptr;
133         napi_async_work work = nullptr;
134         const char *name = nullptr;
135         uint64_t startTime = 0;
136     };
137 
138     struct TaskQueue {
139         ffrt::mutex queuesMutex_;
140         std::queue<InnerTask> taskQueue_;
141         bool isRunning = false;
142     };
143 
144     AsyncCall(napi_env env, napi_callback_info info, std::shared_ptr<Context> context, size_t maxParamCount);
145     ~AsyncCall();
146     napi_value Call(napi_env env, Context::ExecAction exec = nullptr, const std::string &resourceName = "AsyncCall");
147     napi_value Call(napi_env env, Context::AsynExecAction exec = nullptr,
148         const std::string &resourceName = "AsyncCallEx");
149     napi_value Post(napi_env env, Context::ExecAction exec, std::shared_ptr<TaskQueue> queue, const char *func);
150     napi_value SyncCall(napi_env env, Context::ExecAction exec = nullptr);
151 
152 protected:
153     struct AsyncContext {
154         std::shared_ptr<Context> ctx = nullptr;
155         napi_ref callback = nullptr;
156         napi_ref self = nullptr;
157         napi_deferred defer = nullptr;
158         napi_async_work work = nullptr;
159         std::shared_ptr<TaskQueue> queue = nullptr;
160     };
161     static void OnExecuteAsync(napi_env env, AsyncContext *context, Context::CallBackAction cb);
162     static void OnComplete(napi_env env, napi_status status, void *data);
163 
164 private:
165     virtual void CallImpl(napi_env env, AsyncContext *context, const std::string &resourceName);
166 
167 private:
168     enum Arg : int { ARG_ERROR, ARG_DATA, ARG_BUTT };
169     static void OnExecute(napi_env env, void *data);
170     static void OnExecuteSeq(napi_env env, void *data);
171     static void DeleteContext(napi_env env, AsyncContext *context);
172 
173     AsyncContext *context_ = nullptr;
174     napi_env env_ = nullptr;
175 };
176 } // namespace MiscServices
177 } // namespace OHOS
178 #endif // ASYNC_CALL_H
179