14d6c458bSopenharmony_ci/* 24d6c458bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 34d6c458bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44d6c458bSopenharmony_ci * you may not use this file except in compliance with the License. 54d6c458bSopenharmony_ci * You may obtain a copy of the License at 64d6c458bSopenharmony_ci * 74d6c458bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84d6c458bSopenharmony_ci * 94d6c458bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104d6c458bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114d6c458bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124d6c458bSopenharmony_ci * See the License for the specific language governing permissions and 134d6c458bSopenharmony_ci * limitations under the License. 144d6c458bSopenharmony_ci */ 154d6c458bSopenharmony_ci 164d6c458bSopenharmony_ci#ifndef JS_CONCURRENT_MODULE_UTILS_LOCKS_ASYNC_LOCK_H 174d6c458bSopenharmony_ci#define JS_CONCURRENT_MODULE_UTILS_LOCKS_ASYNC_LOCK_H 184d6c458bSopenharmony_ci 194d6c458bSopenharmony_ci#include <list> 204d6c458bSopenharmony_ci#include <string> 214d6c458bSopenharmony_ci#include "common.h" 224d6c458bSopenharmony_ci#include "lock_request.h" 234d6c458bSopenharmony_ci#include "helper/error_helper.h" 244d6c458bSopenharmony_ci#include "helper/napi_helper.h" 254d6c458bSopenharmony_ci#include "helper/object_helper.h" 264d6c458bSopenharmony_ci 274d6c458bSopenharmony_cinamespace Commonlibrary::Concurrent::LocksModule { 284d6c458bSopenharmony_ci 294d6c458bSopenharmony_cistruct RequestCreationInfo { 304d6c458bSopenharmony_ci tid_t tid; 314d6c458bSopenharmony_ci std::string creationStacktrace; 324d6c458bSopenharmony_ci}; 334d6c458bSopenharmony_ci 344d6c458bSopenharmony_ciclass AsyncLock { 354d6c458bSopenharmony_cipublic: 364d6c458bSopenharmony_ci explicit AsyncLock(const std::string &lockName); 374d6c458bSopenharmony_ci explicit AsyncLock(uint32_t lockId); 384d6c458bSopenharmony_ci ~AsyncLock() = default; 394d6c458bSopenharmony_ci 404d6c458bSopenharmony_ci napi_value LockAsync(napi_env env, napi_ref cb, LockMode mode, const LockOptions &options); 414d6c458bSopenharmony_ci void CleanUpLockRequestOnCompletion(LockRequest* lockRequest); 424d6c458bSopenharmony_ci bool CleanUpLockRequestOnTimeout(LockRequest* lockRequest); 434d6c458bSopenharmony_ci napi_status FillLockState(napi_env env, napi_value held, napi_value pending); 444d6c458bSopenharmony_ci void ProcessPendingLockRequest(napi_env env, LockRequest* syncLockRequest = nullptr); 454d6c458bSopenharmony_ci 464d6c458bSopenharmony_ci // Increment the reference counter 474d6c458bSopenharmony_ci uint32_t IncRefCount(); 484d6c458bSopenharmony_ci // Decrement the reference counter. 494d6c458bSopenharmony_ci // When the counter gets 0 the method deletes the instance if possible. 504d6c458bSopenharmony_ci // Any way you cannot use the instance if the method returns 0. 514d6c458bSopenharmony_ci uint32_t DecRefCount(); 524d6c458bSopenharmony_ci 534d6c458bSopenharmony_ci std::vector<RequestCreationInfo> GetSatisfiedRequestInfos(); 544d6c458bSopenharmony_ci std::vector<RequestCreationInfo> GetPendingRequestInfos(); 554d6c458bSopenharmony_ci 564d6c458bSopenharmony_ci std::string GetLockName() const 574d6c458bSopenharmony_ci { 584d6c458bSopenharmony_ci return lockName_; 594d6c458bSopenharmony_ci } 604d6c458bSopenharmony_ci uint32_t GetLockId() const 614d6c458bSopenharmony_ci { 624d6c458bSopenharmony_ci return anonymousLockId_; 634d6c458bSopenharmony_ci } 644d6c458bSopenharmony_ci 654d6c458bSopenharmony_ciprivate: 664d6c458bSopenharmony_ci bool CanAcquireLock(LockRequest *lockRequest); 674d6c458bSopenharmony_ci napi_value CreateLockInfo(napi_env env, const LockRequest *rq); 684d6c458bSopenharmony_ci void AsyncDestroy(napi_env env); 694d6c458bSopenharmony_ci static void AsyncDestroyCallback(napi_env env, napi_status status, void *data); 704d6c458bSopenharmony_ci template<bool isAsync> 714d6c458bSopenharmony_ci void ProcessLockRequest(LockRequest* lockRequest); 724d6c458bSopenharmony_ci void ProcessPendingLockRequestUnsafe(napi_env env, LockRequest* syncLockRequest = nullptr); 734d6c458bSopenharmony_ci 744d6c458bSopenharmony_ci std::list<LockRequest *> pendingList_ {}; 754d6c458bSopenharmony_ci std::list<LockRequest *> heldList_ {}; 764d6c458bSopenharmony_ci LockMode lockStatus_ = LOCK_MODE_UNLOCK; 774d6c458bSopenharmony_ci std::string lockName_ = ""; // "" for anonymous lock 784d6c458bSopenharmony_ci uint32_t anonymousLockId_ {}; // 0 for Non-anonymous lock 794d6c458bSopenharmony_ci std::mutex asyncLockMutex_; 804d6c458bSopenharmony_ci uint32_t refCount_ = 1; 814d6c458bSopenharmony_ci}; 824d6c458bSopenharmony_ci 834d6c458bSopenharmony_ci} // namespace Commonlibrary::Concurrent::LocksModule 844d6c458bSopenharmony_ci#endif // JS_CONCURRENT_MODULE_UTILS_LOCKS_ASYNC_LOCK_H 85