1 /*
2  * Copyright (c) 2024 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 ARK_WEB_BASE_REF_COUNTED_H_
17 #define ARK_WEB_BASE_REF_COUNTED_H_
18 #pragma once
19 
20 #include <atomic>
21 #include <memory>
22 
23 namespace OHOS::ArkWeb {
24 
25 ///
26 /// Class that implements atomic reference counting.
27 ///
28 class ArkWebRefCount {
29 public:
ArkWebRefCount()30     ArkWebRefCount() : ref_count_(0) {}
31 
32     ArkWebRefCount(const ArkWebRefCount&) = delete;
33     ArkWebRefCount& operator=(const ArkWebRefCount&) = delete;
34 
35     /**
36      * @brief The reference count increment 1.
37      */
IncreRef()38     void IncreRef() const
39     {
40         ref_count_.fetch_add(1, std::memory_order_relaxed);
41     }
42 
43     /**
44      * @brief The reference count decrement 1 and returns true if the reference
45      *        count is 0.
46      */
DecreRef()47     bool DecreRef() const
48     {
49         return ref_count_.fetch_sub(1, std::memory_order_acq_rel) == 1;
50     }
51 
52     /**
53      * @brief Returns the reference count.
54      */
GetRefCount()55     int GetRefCount() const
56     {
57         return ref_count_.load(std::memory_order_acquire);
58     }
59 
60 private:
61     mutable std::atomic_int ref_count_;
62 };
63 
64 ///
65 /// All ref-counted framework classes must extend this class.
66 ///
67 class ArkWebBaseRefCounted {
68 public:
69     /**
70      * @brief The reference count increment 1. Should be called for every new copy
71      *        of a pointer to a given object.
72      */
73     virtual void IncreRef() const = 0;
74 
75     /**
76      * @brief The reference count decrement 1 and delete the object when the
77      *        reference count is 0
78      */
79     virtual void DecreRef() const = 0;
80 
81 protected:
~ArkWebBaseRefCounted()82     virtual ~ArkWebBaseRefCounted() {}
83 };
84 
85 ///
86 /// Macro that provides a reference counting implementation for classes
87 /// extending ArkWebBaseRefCounted.
88 ///
89 #define IMPLEMENT_REFCOUNTING(ClassName)                \
90 public:                                                 \
91     void IncreRef() const override                      \
92     {                                                   \
93         ref_count_.IncreRef();                          \
94     }                                                   \
95     void DecreRef() const override                      \
96     {                                                   \
97         if (ref_count_.DecreRef()) {                    \
98             delete static_cast<const ClassName*>(this); \
99         }                                               \
100     }                                                   \
101                                                         \
102 private:                                                \
103     ArkWebRefCount ref_count_
104 
105 } // namespace OHOS::ArkWeb
106 
107 #endif // ARK_WEB_BASE_REF_COUNTED_H_
108