Arcane  v3.14.10.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-2024 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-2024 */
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
41ExternalReferenceCounterAccessor<T>::
42addReference(T* t)
43{
44 if constexpr (impl::HasInternalAddReference<T>::value)
45 t->_internalAddReference();
46 else
47 t->addReference();
48}
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
52
53template <class T> ARCCORE_EXPORT void
54ExternalReferenceCounterAccessor<T>::
55removeReference(T* t)
56{
57 if constexpr (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/*---------------------------------------------------------------------------*/
79class ARCCORE_BASE_EXPORT ReferenceCounterImpl
80{
81 template <typename InstanceType> friend class impl::ReferenceCounterWrapper;
82
83 public:
84
85 virtual ~ReferenceCounterImpl() = default;
86
87 public:
88
89 // TODO: Rendre obsolète
90 void addReference()
91 {
92 ++m_nb_ref;
93 }
94
95 // TODO: Rendre obsolète
96 void removeReference()
97 {
98 // Décrémente et retourne la valeur d'avant.
99 // Si elle vaut 1, cela signifie qu'on n'a plus de références
100 // sur l'objet et qu'il faut le détruire.
101 Int32 v = std::atomic_fetch_add(&m_nb_ref, -1);
102 if (v == 1) {
103 if (_destroyThisReference())
104 delete this;
105 }
106 }
107
108 public:
109
110 void _internalAddReference()
111 {
112 ++m_nb_ref;
113 }
114 bool _internalRemoveReference()
115 {
116 // Décrémente et retourne la valeur d'avant.
117 // Si elle vaut 1, cela signifie qu'on n'a plus de références
118 // sur l'objet et qu'il faut éventuellement le détruire.
119 Int32 v = std::atomic_fetch_add(&m_nb_ref, -1);
120 if (v == 1)
121 return _destroyThisReference();
122 return false;
123 }
124
125 private:
126
127 // Méthodes accessibles uniquement depuis ReferenceCounterWrapper
128 void _setExternalDeleter(RefBase::DeleterBase* v)
129 {
130 delete m_external_deleter;
131 m_external_deleter = v;
132 }
133 RefBase::DeleterBase* _externalDeleter() const
134 {
135 return m_external_deleter;
136 }
137
138 private:
139
140 std::atomic<Int32> m_nb_ref = 0;
141 RefBase::DeleterBase* m_external_deleter = nullptr;
142
143 private:
144
147 {
148 if (!m_external_deleter)
149 return true;
150 bool do_delete = false;
151 if (!m_external_deleter->m_no_destroy) {
152 bool is_destroyed = m_external_deleter->_destroyHandle(this, m_external_deleter->m_handle);
153 if (!is_destroyed) {
154 do_delete = true;
155 }
156 }
157 delete m_external_deleter;
158 m_external_deleter = nullptr;
159 return do_delete;
160 }
161};
162
163/*---------------------------------------------------------------------------*/
164/*---------------------------------------------------------------------------*/
169#define ARCCORE_INTERNAL_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS(OPTIONAL_OVERRIDE) \
170 private: \
171\
172 using BaseCounterType = ::Arccore::ReferenceCounterImpl; \
173\
174 public: \
175\
176 BaseCounterType* _internalReferenceCounter() OPTIONAL_OVERRIDE \
177 { \
178 return this; \
179 } \
180 void _internalAddReference() OPTIONAL_OVERRIDE \
181 { \
182 BaseCounterType::_internalAddReference(); \
183 } \
184 bool _internalRemoveReference() OPTIONAL_OVERRIDE \
185 { \
186 return BaseCounterType::_internalRemoveReference(); \
187 }
188
189/*---------------------------------------------------------------------------*/
190/*---------------------------------------------------------------------------*/
211#define ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS() \
212 ARCCORE_INTERNAL_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS(override)
213
214/*---------------------------------------------------------------------------*/
215/*---------------------------------------------------------------------------*/
216
233#define ARCCORE_DEFINE_REFERENCE_COUNTED_CLASS(class_name) \
234 template class ExternalReferenceCounterAccessor<class_name>
235
236/*---------------------------------------------------------------------------*/
237/*---------------------------------------------------------------------------*/
238
239} // End namespace Arccore
240
241/*---------------------------------------------------------------------------*/
242/*---------------------------------------------------------------------------*/
243
244#endif
bool m_no_destroy
Indique si on doit appeler le destructeur de l'instance lorsqu'il n'y a plus de références dessus.
Definition RefBase.h:80
Internal::ExternalRef m_handle
Handle externe qui se charge de la destruction de l'instance.
Definition RefBase.h:75
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.
Espace de nom de Arccore.
Definition ArcaneTypes.h:24
std::int32_t Int32
Type entier signé sur 32 bits.