Arcane  v3.16.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ReferenceCounterImpl.h
Aller à la documentation de ce fichier.
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* ReferenceCounterImpl.h (C) 2000-2025 */
9/* */
10/* Implémentations liées au gestionnaire de compteur de référence. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCCORE_BASE_REFERENCECOUNTERIMPL_H
13#define ARCCORE_BASE_REFERENCECOUNTERIMPL_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arccore/base/ReferenceCounter.h"
18#include "arccore/base/RefBase.h"
19
20#include <atomic>
21
22/*---------------------------------------------------------------------------*/
23/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
34namespace Arccore
35{
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
40template <class T> ARCCORE_EXPORT void
42addReference(T* t)
43{
44 if constexpr (::Arcane::impl::HasInternalAddReference<T>::value)
45 t->_internalAddReference();
46 else
47 t->addReference();
48}
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
52
53template <class T> ARCCORE_EXPORT void
56{
57 if constexpr (::Arcane::impl::HasInternalRemoveReference<T>::value) {
58 bool need_destroy = t->_internalRemoveReference();
59 if (need_destroy)
60 delete t;
61 }
62 else
63 t->removeReference();
64}
65
66/*---------------------------------------------------------------------------*/
67/*---------------------------------------------------------------------------*/
68
69} // namespace Arccore
70
71/*---------------------------------------------------------------------------*/
72/*---------------------------------------------------------------------------*/
73
74namespace Arcane
75{
76
77/*---------------------------------------------------------------------------*/
78/*---------------------------------------------------------------------------*/
90class ARCCORE_BASE_EXPORT ReferenceCounterImpl
91{
92 template <typename InstanceType> friend class impl::ReferenceCounterWrapper;
93
94 public:
95
96 virtual ~ReferenceCounterImpl() = default;
97
98 public:
99
100 // TODO: Rendre obsolète
101 void addReference()
102 {
103 ++m_nb_ref;
104 }
105
106 // TODO: Rendre obsolète
107 void removeReference()
108 {
109 // Décrémente et retourne la valeur d'avant.
110 // Si elle vaut 1, cela signifie qu'on n'a plus de références
111 // sur l'objet et qu'il faut le détruire.
112 Int32 v = std::atomic_fetch_add(&m_nb_ref, -1);
113 if (v == 1) {
115 delete this;
116 }
117 }
118
119 public:
120
121 void _internalAddReference()
122 {
123 ++m_nb_ref;
124 }
125 bool _internalRemoveReference()
126 {
127 // Décrémente et retourne la valeur d'avant.
128 // Si elle vaut 1, cela signifie qu'on n'a plus de références
129 // sur l'objet et qu'il faut éventuellement le détruire.
130 Int32 v = std::atomic_fetch_add(&m_nb_ref, -1);
131 if (v == 1)
132 return _destroyThisReference();
133 return false;
134 }
135
136 private:
137
138 // Méthodes accessibles uniquement depuis ReferenceCounterWrapper
139 void _setExternalDeleter(RefBase::DeleterBase* v)
140 {
141 delete m_external_deleter;
142 m_external_deleter = v;
143 }
144 RefBase::DeleterBase* _externalDeleter() const
145 {
146 return m_external_deleter;
147 }
148
149 private:
150
151 std::atomic<Int32> m_nb_ref = 0;
152 RefBase::DeleterBase* m_external_deleter = nullptr;
153
154 private:
155
158 {
159 if (!m_external_deleter)
160 return true;
161 bool do_delete = false;
162 if (!m_external_deleter->m_no_destroy) {
163 bool is_destroyed = m_external_deleter->_destroyHandle(this, m_external_deleter->m_handle);
164 if (!is_destroyed) {
165 do_delete = true;
166 }
167 }
168 delete m_external_deleter;
169 m_external_deleter = nullptr;
170 return do_delete;
171 }
172};
173
174/*---------------------------------------------------------------------------*/
175/*---------------------------------------------------------------------------*/
180#define ARCCORE_INTERNAL_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS(OPTIONAL_OVERRIDE) \
181 private: \
182\
183 using BaseCounterType = ::Arcane::ReferenceCounterImpl; \
184\
185 public: \
186\
187 BaseCounterType* _internalReferenceCounter() OPTIONAL_OVERRIDE \
188 { \
189 return this; \
190 } \
191 void _internalAddReference() OPTIONAL_OVERRIDE \
192 { \
193 BaseCounterType::_internalAddReference(); \
194 } \
195 bool _internalRemoveReference() OPTIONAL_OVERRIDE \
196 { \
197 return BaseCounterType::_internalRemoveReference(); \
198 }
199
200/*---------------------------------------------------------------------------*/
201/*---------------------------------------------------------------------------*/
222#define ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS() \
223 ARCCORE_INTERNAL_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS(override)
224
225/*---------------------------------------------------------------------------*/
226/*---------------------------------------------------------------------------*/
227
244#define ARCCORE_DEFINE_REFERENCE_COUNTED_CLASS(class_name) \
245 template class ExternalReferenceCounterAccessor<class_name>
246
247/*---------------------------------------------------------------------------*/
248/*---------------------------------------------------------------------------*/
249
250} // End namespace Arccore
251
252/*---------------------------------------------------------------------------*/
253/*---------------------------------------------------------------------------*/
254
255#endif
Implémentation thread-safe d'un compteur de référence.
bool _destroyThisReference()
Retourne true si l'instance doit être détruite par l'appel à operator delete()
Wrapper autour d'une classe gérant son propre compteur de référence.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int32_t Int32
Type entier signé sur 32 bits.
Espace de nom de Arccore.