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 19NativeCallbackScope::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 36NativeCallbackScope::~NativeCallbackScope() 37{ 38 Close(); 39} 40 41void 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 78NativeCallbackScopeManager::NativeCallbackScopeManager() {} 79 80NativeCallbackScopeManager::~NativeCallbackScopeManager() {} 81 82NativeCallbackScope* 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 96void NativeCallbackScopeManager::Close(NativeCallbackScope* scope) 97{ 98 if (scope != nullptr) { 99 delete scope; 100 } 101 asyncCallbackScopeDepth_--; 102} 103 104size_t NativeCallbackScopeManager::IncrementOpenCallbackScopes() 105{ 106 openCallbackScopes_++; 107 return openCallbackScopes_; 108} 109 110size_t NativeCallbackScopeManager::DecrementOpenCallbackScopes() 111{ 112 openCallbackScopes_--; 113 return openCallbackScopes_; 114} 115