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 #include "native_callback_scope_manager.h"
17 #include "native_engine/native_engine.h"
18
NativeCallbackScope(NativeEngine * env,panda::Local<panda::ObjectRef> object,const AsyncIdInfo & asyncIdInfo,int flags)19 NativeCallbackScope::NativeCallbackScope(NativeEngine* env,
20 panda::Local<panda::ObjectRef> object,
21 const AsyncIdInfo& asyncIdInfo,
22 int flags) : env_(env), asyncIdInfo_(asyncIdInfo),
23 object_(object), skipHooks_(flags & SKIP_ASYNC_HOOKS), skipTaskQueues_(flags & SKIP_TASK_QUEUES)
24 {
25 [[maybe_unused]] panda::LocalScope scope(env_->GetEcmaVm());
26
27 // not support async_hook yet, and push_async_context actions need to be improved in the future
28
29 pushedIds_ = true;
30
31 if (asyncIdInfo.asyncId != 0 && !skipHooks_) {
32 NativeAsyncWrap::EmitBefore(env, asyncIdInfo.asyncId);
33 }
34 }
35
~NativeCallbackScope()36 NativeCallbackScope::~NativeCallbackScope()
37 {
38 Close();
39 }
40
Close()41 void NativeCallbackScope::Close()
42 {
43 if (closed_) {
44 return;
45 }
46 closed_ = true;
47
48 auto performStoppingCheck = [this]() {
49 if (env_->IsStopping()) {
50 MarkAsFailed();
51 // not support async_hook yet, and clear_async_id_stack actions need to be improved in the future
52 }
53 };
54 performStoppingCheck();
55
56 if (env_->IsStopping()) {
57 return;
58 }
59
60 if (!failed_ && asyncIdInfo_.asyncId != 0 && !skipHooks_) {
61 NativeAsyncWrap::EmitAfter(env_, asyncIdInfo_.asyncId);
62 }
63
64 if (pushedIds_) {
65 pushedIds_ = false;
66 // not support async_hook yet, and pop_async_context actions need to be improved in the future
67 }
68
69 if (failed_) {
70 return;
71 }
72
73 if (env_->GetCallbackScopeManager()->GetOpenCallbackScopes() > 1 || skipTaskQueues_) {
74 return;
75 }
76 }
77
NativeCallbackScopeManager()78 NativeCallbackScopeManager::NativeCallbackScopeManager() {}
79
~NativeCallbackScopeManager()80 NativeCallbackScopeManager::~NativeCallbackScopeManager() {}
81
Open(NativeEngine * env,panda::Local<panda::ObjectRef> object,AsyncIdInfo asyncIdInfo)82 NativeCallbackScope* NativeCallbackScopeManager::Open(NativeEngine* env,
83 panda::Local<panda::ObjectRef> object,
84 AsyncIdInfo asyncIdInfo)
85 {
86 NativeCallbackScope* scope = new (std::nothrow)NativeCallbackScope(env, object, asyncIdInfo);
87
88 if (scope) {
89 asyncCallbackScopeDepth_++;
90 return scope;
91 } else {
92 return nullptr;
93 }
94 }
95
Close(NativeCallbackScope * scope)96 void NativeCallbackScopeManager::Close(NativeCallbackScope* scope)
97 {
98 if (scope != nullptr) {
99 delete scope;
100 }
101 asyncCallbackScopeDepth_--;
102 }
103
IncrementOpenCallbackScopes()104 size_t NativeCallbackScopeManager::IncrementOpenCallbackScopes()
105 {
106 openCallbackScopes_++;
107 return openCallbackScopes_;
108 }
109
DecrementOpenCallbackScopes()110 size_t NativeCallbackScopeManager::DecrementOpenCallbackScopes()
111 {
112 openCallbackScopes_--;
113 return openCallbackScopes_;
114 }
115