1/*
2 * Copyright (c) 2022 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#ifndef ECMASCRIPT_WAITER_LIST_H
17#define ECMASCRIPT_WAITER_LIST_H
18
19#include "ecmascript/ecma_macros.h"
20#include "ecmascript/mem/c_containers.h"
21
22#include "ecmascript/platform/mutex.h"
23
24namespace panda::ecmascript {
25class WaiterListNode {
26public:
27    WaiterListNode() = default;
28    ~WaiterListNode() = default;
29
30    NO_COPY_SEMANTIC(WaiterListNode);
31    NO_MOVE_SEMANTIC(WaiterListNode);
32
33    WaiterListNode *prev_ {nullptr};
34    WaiterListNode *next_ {nullptr};
35    // Used to call wait or Signal() to unlock wait and wake up
36    ConditionVariable cond_;
37
38    // Managed Arraybuffer or SharedArrayBuffer memory data
39    void *date_ {nullptr};
40
41    // the offset of the element in the typedArray
42    size_t index_ {0};
43
44    // the memory address data corresponding to the offset
45    int8_t *waitPointer_ {nullptr};
46
47    // used to determine whether to wait, start wait when waiting_ is true
48    bool waiting_ {false};
49
50private:
51    friend class WaiterList;
52};
53
54// WaiterList to manage WaiterListNode
55class WaiterList {
56public:
57    WaiterList() = default;
58    ~WaiterList() = default;
59    void AddNode(WaiterListNode *node);
60    void DeleteNode(WaiterListNode *node);
61    struct HeadAndTail {
62        WaiterListNode *pHead {nullptr};
63        WaiterListNode *pTail {nullptr};
64    };
65
66    // locationListMap_  is used AddNode or DeleteNode
67    // When calling addnode If there is no corresponding memory data, add the node corresponding to the key
68    CMap<int8_t *, HeadAndTail> locationListMap_;
69};
70
71// The Singleton pattern is used to creat a global metux and WaiterList
72template <class T>
73class Singleton {
74public:
75    ~Singleton() {}
76    NO_COPY_SEMANTIC(Singleton);
77    NO_MOVE_SEMANTIC(Singleton);
78    static T *GetInstance()
79    {
80        static T instance;
81        return &instance;
82    }
83
84private:
85    Singleton() = default;
86};
87
88class MutexGuard {
89public:
90    explicit MutexGuard(Mutex *mutex) : mutex_(mutex), lockHolder_(*mutex) {}
91    void Unlock()
92    {
93        mutex_->Unlock();
94    }
95
96    void Lock()
97    {
98        mutex_->Lock();
99    }
100private:
101    Mutex *mutex_;
102    LockHolder lockHolder_;
103};
104}  // namespace
105#endif  // ECMASCRIPT_WAITER_LIST_H
106