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_LOCK_REQUEST_H
174d6c458bSopenharmony_ci#define JS_CONCURRENT_MODULE_UTILS_LOCKS_LOCK_REQUEST_H
184d6c458bSopenharmony_ci
194d6c458bSopenharmony_ci#include <queue>
204d6c458bSopenharmony_ci#include <string>
214d6c458bSopenharmony_ci#include "common.h"
224d6c458bSopenharmony_ci#include "helper/error_helper.h"
234d6c458bSopenharmony_ci#include "helper/napi_helper.h"
244d6c458bSopenharmony_ci#include "helper/object_helper.h"
254d6c458bSopenharmony_ci
264d6c458bSopenharmony_cinamespace Commonlibrary::Concurrent::LocksModule {
274d6c458bSopenharmony_cienum LockMode {
284d6c458bSopenharmony_ci    LOCK_MODE_UNLOCK,
294d6c458bSopenharmony_ci    LOCK_MODE_SHARED,
304d6c458bSopenharmony_ci    LOCK_MODE_EXCLUSIVE,
314d6c458bSopenharmony_ci    LOCK_MODE_MAX
324d6c458bSopenharmony_ci};
334d6c458bSopenharmony_ci
344d6c458bSopenharmony_cistruct LockOptions {
354d6c458bSopenharmony_ci    bool isAvailable = false;
364d6c458bSopenharmony_ci    napi_ref signal = nullptr;
374d6c458bSopenharmony_ci    uint32_t timeoutMillis = 0;
384d6c458bSopenharmony_ci};
394d6c458bSopenharmony_ci
404d6c458bSopenharmony_ciclass AsyncLock;
414d6c458bSopenharmony_ci
424d6c458bSopenharmony_ciclass LockRequest {
434d6c458bSopenharmony_cipublic:
444d6c458bSopenharmony_ci    LockRequest(AsyncLock* lock, tid_t tid, napi_env env, napi_ref cb, LockMode mode, const LockOptions &options,
454d6c458bSopenharmony_ci        napi_deferred deferred);
464d6c458bSopenharmony_ci    ~LockRequest();
474d6c458bSopenharmony_ci
484d6c458bSopenharmony_ci    tid_t GetTid() const
494d6c458bSopenharmony_ci    {
504d6c458bSopenharmony_ci        return tid_;
514d6c458bSopenharmony_ci    }
524d6c458bSopenharmony_ci
534d6c458bSopenharmony_ci    std::string GetCreationStacktrace()
544d6c458bSopenharmony_ci    {
554d6c458bSopenharmony_ci        return creationStacktrace_;
564d6c458bSopenharmony_ci    }
574d6c458bSopenharmony_ci
584d6c458bSopenharmony_ci    LockMode GetMode() const
594d6c458bSopenharmony_ci    {
604d6c458bSopenharmony_ci        return mode_;
614d6c458bSopenharmony_ci    }
624d6c458bSopenharmony_ci
634d6c458bSopenharmony_ci    const LockOptions &GetOptions() const
644d6c458bSopenharmony_ci    {
654d6c458bSopenharmony_ci        return options_;
664d6c458bSopenharmony_ci    }
674d6c458bSopenharmony_ci
684d6c458bSopenharmony_ci    napi_env GetEnv()
694d6c458bSopenharmony_ci    {
704d6c458bSopenharmony_ci        return env_;
714d6c458bSopenharmony_ci    }
724d6c458bSopenharmony_ci
734d6c458bSopenharmony_ci    void CallCallbackAsync();
744d6c458bSopenharmony_ci    void CallCallback();
754d6c458bSopenharmony_ci
764d6c458bSopenharmony_ci    void OnQueued(uint32_t timeoutMillis);
774d6c458bSopenharmony_ci    void OnSatisfied();
784d6c458bSopenharmony_ciprivate:
794d6c458bSopenharmony_ci    bool AbortIfNeeded();
804d6c458bSopenharmony_ci    void ArmTimeoutTimer(uint32_t timeoutMillis);
814d6c458bSopenharmony_ci    void DisarmTimeoutTimer();
824d6c458bSopenharmony_ci    void HandleRequestTimeout(std::string &&errorMessage);
834d6c458bSopenharmony_ci    std::string GetLockInfo() const;
844d6c458bSopenharmony_ci    void CleanTimer();
854d6c458bSopenharmony_ci    static void AsyncAfterWorkCallback(napi_env env, napi_status status, void *data);
864d6c458bSopenharmony_ci    static napi_value FinallyCallback(napi_env env, napi_callback_info info);
874d6c458bSopenharmony_ci    static void TimeoutCallback(uv_timer_t *handle);
884d6c458bSopenharmony_ci    static void DeallocateTimeoutTimerCallback(uv_handle_t* handle);
894d6c458bSopenharmony_ci    static void EnvCleanUp(void* arg);
904d6c458bSopenharmony_ci
914d6c458bSopenharmony_ci    AsyncLock* lock_;
924d6c458bSopenharmony_ci    tid_t tid_;
934d6c458bSopenharmony_ci    std::string creationStacktrace_;
944d6c458bSopenharmony_ci    napi_env env_;
954d6c458bSopenharmony_ci    napi_ref callback_;
964d6c458bSopenharmony_ci    LockMode mode_;
974d6c458bSopenharmony_ci    LockOptions options_;
984d6c458bSopenharmony_ci    napi_deferred deferred_;
994d6c458bSopenharmony_ci    napi_async_work work_;
1004d6c458bSopenharmony_ci    uv_timer_t *timeoutTimer_;
1014d6c458bSopenharmony_ci    bool timeoutActive_;
1024d6c458bSopenharmony_ci    std::mutex lockRequestMutex_;
1034d6c458bSopenharmony_ci};
1044d6c458bSopenharmony_ci
1054d6c458bSopenharmony_cistruct RequestTimeoutData {
1064d6c458bSopenharmony_ci    RequestTimeoutData(AsyncLock* l, LockRequest* r): lock(l), request(r) {}
1074d6c458bSopenharmony_ci    AsyncLock* lock;
1084d6c458bSopenharmony_ci    LockRequest* request;
1094d6c458bSopenharmony_ci};
1104d6c458bSopenharmony_ci
1114d6c458bSopenharmony_ci}  // namespace Commonlibrary::Concurrent::LocksModule
1124d6c458bSopenharmony_ci#endif  // JS_CONCURRENT_MODULE_UTILS_LOCKS_LOCK_REQUEST_H
113