• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 NAPI_ASYNC_WORK_H
16 #define NAPI_ASYNC_WORK_H
17 
18 #include <functional>
19 #include <memory>
20 #include <string>
21 #include <uv.h>
22 
23 #include "napi/native_api.h"
24 #include "napi/native_common.h"
25 #include "napi/native_node_api.h"
26 #include "drm_error_code.h"
27 #include "napi_param_utils.h"
28 
29 namespace OHOS {
30 namespace DrmStandard {
31 using NapiCbInfoParser = std::function<void(size_t argc, napi_value *argv)>;
32 using NapiAsyncExecute = std::function<void(void)>;
33 using NapiAsyncComplete = std::function<void(napi_value&)>;
34 
35 struct ContextBase {
36     virtual ~ContextBase();
37     void GetCbInfo(napi_env env, napi_callback_info info, NapiCbInfoParser parse = NapiCbInfoParser(),
38         bool sync = false);
39     void SignError(int32_t code);
40     napi_env env = nullptr;
41     napi_value output = nullptr;
42     napi_status status = napi_invalid_arg;
43     std::string errMessage;
44     int32_t errCode;
45     napi_value self = nullptr;
46     void* native = nullptr;
47     std::string taskName;
48 
49 private:
50     napi_deferred deferred = nullptr;
51     napi_async_work work = nullptr;
52     napi_ref callbackRef = nullptr;
53     napi_ref selfRef = nullptr;
54 
55     NapiAsyncExecute execute = nullptr;
56     NapiAsyncComplete complete = nullptr;
57     std::shared_ptr<ContextBase> hold; /* cross thread data */
58 
59     static constexpr size_t ARGC_MAX = 6;
60 
61     friend class NapiAsyncWork;
62 };
63 
64 struct NapiWorkData {
65     napi_env env_;
66     napi_ref cb_;
67 };
68 
69 struct AutoRef {
AutoRefAutoRef70     AutoRef(napi_env env, napi_ref cb)
71         : env_(env), cb_(cb)
72     {
73     }
~AutoRefAutoRef74     ~AutoRef()
75     {
76         uv_loop_s *loop = nullptr;
77         napi_get_uv_event_loop(env_, &loop);
78         if (loop == nullptr) {
79             return;
80         }
81 
82         NapiWorkData *workData = new (std::nothrow) NapiWorkData();
83         if (workData == nullptr) {
84             return;
85         }
86         workData->env_ = env_;
87         workData->cb_ = cb_;
88 
89         uv_work_t *work = new(std::nothrow) uv_work_t;
90         if (work == nullptr) {
91             delete workData;
92             workData = nullptr;
93             return;
94         }
95         work->data = (void *)workData;
96 
97         int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {}, [] (uv_work_t *work, int status) {
98             // Js thread
99             NapiWorkData *workData = reinterpret_cast<NapiWorkData *>(work->data);
100             napi_env env = workData->env_;
101             napi_ref cb = workData->cb_;
102             if (env != nullptr && cb != nullptr) {
103                 (void)napi_delete_reference(env, cb);
104             }
105             delete workData;
106             delete work;
107         }, uv_qos_default);
108         if (ret != 0) {
109             delete work;
110             work = nullptr;
111             delete workData;
112             workData = nullptr;
113         }
114     }
115     napi_env env_;
116     napi_ref cb_;
117 };
118 
119 class NapiAsyncWork {
120 public:
121     static napi_value Enqueue(napi_env env, std::shared_ptr<ContextBase> ctxt, const std::string &name,
122         NapiAsyncExecute execute = NapiAsyncExecute(),
123         NapiAsyncComplete complete = NapiAsyncComplete());
124 
125 private:
126     enum {
127         /* AsyncCallback / Promise output result index  */
128         RESULT_ERROR = 0,
129         RESULT_DATA = 1,
130         RESULT_ALL = 2
131     };
132     static void CommonCallbackRoutine(ContextBase *ctxt);
133 };
134 } // namespace DrmStandard
135 } // namespace OHOS
136 #endif // NAPI_ASYNC_WORK_H