Skip to content

Commit 52416c0

Browse files
committed
Add wrapper class to handle cleanup of static pointers
Remove code for cleanup of static variables Prevent leak of Variables pointer in consecutive calls to driver run Added missing value set definition call (to initialize _adjustments) in Variables
1 parent d731dbb commit 52416c0

File tree

6 files changed

+114
-123
lines changed

6 files changed

+114
-123
lines changed

include/ValueSet.hpp

Lines changed: 31 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@
3030
#include "enums/enums_utils.hpp"
3131
#include <iomanip>
3232

33-
void cleanup_value_sets();
34-
void register_value_set_cleanup();
35-
3633
#define CHECK_RATIO_IDX(act, exp, key) \
3734
if (it->first == key && act != exp) { \
3835
throw std::runtime_error("CHECK[" + utils::enum_key2string(key) \
@@ -47,7 +44,7 @@ namespace ePhotosynthesis {
4744
#define DO_VALUE_SET_CHILD_CLASSES_MACRO(macro, iter, ...) \
4845
if (!noChildren) { \
4946
size_t iChild = 0; \
50-
for (std::vector<ValueSetClass_t*>::iter it = child_classes.begin(); \
47+
for (std::vector<ValueSetClassWrapper>::iter it = child_classes.begin(); \
5148
it != child_classes.end(); it++, iChild++) { \
5249
if (*it) { \
5350
macro((*it), __VA_ARGS__); \
@@ -155,7 +152,7 @@ namespace ePhotosynthesis {
155152

156153
#define VALUE_SET_PARENT(cls, par, mod, pt) ValueSet<cls, par, mod, pt>
157154
#define VALUE_SET_STATIC_PARENT(cls, par, mod, pt) ValueSetStatic<cls, par, mod, pt>
158-
155+
159156
#define DECLARE_VALUE_SET_MEMBER_RECORD \
160157
static const StaticMemberClass _adjustments
161158
#define DEFINE_VALUE_SET_MEMBER_RECORD(prefix, name) \
@@ -182,7 +179,6 @@ namespace ePhotosynthesis {
182179
extern ValueSetStaticClassType<name>
183180
*/
184181
#define DECLARE_VALUE_SET_CORE(name) \
185-
typedef _valueSetStaticMember<name> StaticMemberClass; \
186182
DECLARE_VALUE_SET_MEMBER_RECORD;
187183
#define DECLARE_VALUE_SET_MEMBERS(name) \
188184
FOR_EACH(DECLARE_VALUE_SET_MEMBER, EXPAND(MEMBERS_ ## name)); \
@@ -291,7 +287,6 @@ namespace ePhotosynthesis {
291287
public:
292288
#define DECLARE_VALUE_SET_STATIC_CORE(name, ...) \
293289
DECLARE_VALUE_SET_STATIC_BASE(name, __VA_ARGS__) \
294-
typedef _valueSetStaticMember<name> StaticMemberClass; \
295290
friend Value<name>; \
296291
friend _valueSetStaticMember<name>; \
297292
DECLARE_VALUE_SET_MEMBER_RECORD;
@@ -318,9 +313,6 @@ namespace ePhotosynthesis {
318313
_valueSetStaticMember() {
319314
T::initStaticMembers();
320315
}
321-
~_valueSetStaticMember() {
322-
T::cleanupStaticMembers();
323-
}
324316
};
325317

326318
#define VALUE_X_PTR 1
@@ -564,15 +556,9 @@ namespace ePhotosynthesis {
564556
/** \copydoc ValueSetBase::initChildClasses */ \
565557
method(initChildClasses, void, \
566558
((const bool, noChildren, false)), , const) \
567-
/** \copydoc ValueSetBase::cleanupChildClasses */ \
568-
method(cleanupChildClasses, void, \
569-
((const bool, noChildren, false)), , const) \
570559
/** \copydoc ValueSetBase::initStaticMembers */ \
571560
method(initStaticMembers, void, \
572561
((const bool, noChildren, false)), , const) \
573-
/** \copydoc ValueSetBase::cleanupStaticMembers */ \
574-
method(cleanupStaticMembers, void, \
575-
((const bool, noChildren, false)), , const) \
576562
/** \copydoc ValueSetBase:selected */ \
577563
method(selected, bool, (), false, const) \
578564
/** \copydoc ValueSetBase::select */ \
@@ -868,6 +854,28 @@ namespace ePhotosynthesis {
868854
#undef DISABLE_METHOD
869855
#undef ADD_METHOD
870856
};
857+
858+
/**
859+
Wrapper for handling destruction of ValueSet pointers.
860+
*/
861+
template<typename T>
862+
class ValueSetWrapperBase {
863+
public:
864+
ValueSetWrapperBase(T* ptr);
865+
ValueSetWrapperBase(ValueSetWrapperBase&& other);
866+
~ValueSetWrapperBase();
867+
ValueSetWrapperBase<T>& operator=(ValueSetWrapperBase&& other);
868+
T* operator->();
869+
const T* operator->() const;
870+
T& operator*();
871+
const T& operator*() const;
872+
operator bool() const;
873+
private:
874+
T* ptr_;
875+
};
876+
877+
typedef ValueSetWrapperBase<ValueSet_t> ValueSetWrapper;
878+
typedef ValueSetWrapperBase<ValueSetClass_t> ValueSetClassWrapper;
871879

872880
/**
873881
Template class to provide core methods for manipulating sets of
@@ -896,6 +904,7 @@ namespace ePhotosynthesis {
896904
typedef Value<BaseClass> ValueType; /**< Class for storing values */
897905
typedef typename std::map<EnumType, double*>::iterator iterator; /**< Iterator type for values in the set */
898906
typedef typename std::map<EnumType, double*>::const_iterator const_iterator; /**< Constant iterator type for values in the set */
907+
typedef _valueSetStaticMember<T> StaticMemberClass;
899908
INHERIT_METHOD_ENUM(EnumBaseClass);
900909

901910
/**
@@ -2377,7 +2386,7 @@ namespace ePhotosynthesis {
23772386
", NONVECT = " + stringNonvector();
23782387
if (noChildren)
23792388
return out;
2380-
for (std::vector<ValueSetClass_t*>::const_iterator it = child_classes.begin();
2389+
for (std::vector<ValueSetClassWrapper>::const_iterator it = child_classes.begin();
23812390
it != child_classes.end(); it++)
23822391
out += "\n\t" + (*it)->memberState();
23832392
return out;
@@ -2389,13 +2398,13 @@ namespace ePhotosynthesis {
23892398
*/
23902399
template<typename C>
23912400
static void addChildClass() {
2392-
child_classes.push_back(new ValueSetClassType<C>());
2401+
child_classes.emplace_back(new ValueSetClassType<C>());
23932402
}
23942403

23952404
static int static_flags; /**< Bitwise flags describing the value set static state */
23962405
static std::map<EnumType, double> defaults; /**< Default values */
23972406
static std::map<EnumType, double*> static_values; /**< Static values */
2398-
static std::vector<ValueSetClass_t*> child_classes; /**< Child classes */
2407+
static std::vector<ValueSetClassWrapper> child_classes; /**< Child classes */
23992408
static const uint tab_size = 2;
24002409

24012410
// Methods that call inheriting class methods
@@ -2410,24 +2419,6 @@ namespace ePhotosynthesis {
24102419
DO_VALUE_SET_CHILD_CLASSES(initChildClasses, ());
24112420
static_flags |= VS_FLAG_INIT_CHILDREN;
24122421
}
2413-
/**
2414-
Clean up the child classes.
2415-
\param noChildren If true, children of child classes will not be
2416-
finalized.
2417-
Common, public interface for the private _cleanupChildClasses
2418-
method.
2419-
*/
2420-
static void cleanupChildClasses(const bool noChildren = false) {
2421-
if (!(static_flags & VS_FLAG_INIT_CHILDREN)) return;
2422-
T::_cleanupChildClasses();
2423-
DO_VALUE_SET_CHILD_CLASSES(cleanupChildClasses, ());
2424-
for (std::size_t i = 0; i < child_classes.size(); i++) {
2425-
delete child_classes[i];
2426-
child_classes[i] = nullptr;
2427-
}
2428-
child_classes.clear();
2429-
static_flags &= ~VS_FLAG_INIT_CHILDREN;
2430-
}
24312422
/**
24322423
Initialize the static class members including child classes.
24332424
\param noChildren If true, child classes will not be initialized.
@@ -2439,19 +2430,6 @@ namespace ePhotosynthesis {
24392430
initChildClasses(true); // Children will be called in initStaticMembers
24402431
DO_VALUE_SET_CHILD_CLASSES(initStaticMembers, ());
24412432
static_flags |= VS_FLAG_INIT_STATIC;
2442-
register_value_set_cleanup();
2443-
}
2444-
/**
2445-
Finalize the static class members.
2446-
Common, public interface for the private _cleanupStaticMembers
2447-
method.
2448-
*/
2449-
static void cleanupStaticMembers(const bool noChildren = false) {
2450-
if (!(static_flags & VS_FLAG_INIT_STATIC)) return;
2451-
T::_cleanupStaticMembers();
2452-
DO_VALUE_SET_CHILD_CLASSES(cleanupStaticMembers, ());
2453-
cleanupChildClasses(true);
2454-
static_flags &= ~VS_FLAG_INIT_STATIC;
24552433
}
24562434
/**
24572435
Check if the value set is selected by the current driver.
@@ -2536,12 +2514,8 @@ namespace ePhotosynthesis {
25362514
static void _initDefaults() {}
25372515
/** Perform class specific child class initialization */
25382516
static void _initChildClasses() {}
2539-
/** Perform class specific child class cleanup */
2540-
static void _cleanupChildClasses() {}
25412517
/** Perform class specific static member initialization */
25422518
static void _initStaticMembers() {}
2543-
/** Perform class specific static member cleanup */
2544-
static void _cleanupStaticMembers() {}
25452519
/** Perform class specific value set selection */
25462520
static void _select(const bool = true, const bool = false) {}
25472521
/** Perform class specific actions to enable C3 */
@@ -2570,7 +2544,7 @@ namespace ePhotosynthesis {
25702544
ValueSetBase<T, U, ID, PT>::static_values = {};
25712545

25722546
template<class T, class U, MODULE ID, PARAM_TYPE PT>
2573-
std::vector<ValueSetClass_t*>
2547+
std::vector<ValueSetClassWrapper>
25742548
ValueSetBase<T, U, ID, PT>::child_classes = {};
25752549

25762550
/**
@@ -2824,7 +2798,7 @@ namespace ePhotosynthesis {
28242798
// child_classes.size(),
28252799
// ") does not match the number of child pointers (",
28262800
// children.size(), ")");
2827-
// std::vector<ValueSetClass_t*>::iterator itCls = child_classes.begin();
2801+
// std::vector<ValueSetClassWrapper>::iterator itCls = child_classes.begin();
28282802
// for (std::vector<ValueSet_t**>::iterator it = children.begin();
28292803
// it != children.end(); it++, itCls++) {
28302804
// if (**it) continue;
@@ -3464,7 +3438,7 @@ namespace ePhotosynthesis {
34643438
}
34653439
/** Get the constant iterator pointing to the start of the value set */
34663440
// Inspection utilities
3467-
/** \copydoc ValueSetClass_t::max_value_width */
3441+
/** \copydoc ValueSet::max_value_width */
34683442
static std::size_t max_value_width(bool noChildren = false) {
34693443
static std::size_t out = 0;
34703444
static std::size_t outBase = 0;

include/Variables.hpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -591,20 +591,6 @@ class Variables : public VALUE_SET_PARENT(Variables, Variables, MODULE_ALL, PARA
591591
const std::map<MODULE, const ValueSet_t*>& conditions = {},
592592
const std::string& error_context = "") const;
593593

594-
/**
595-
Cleanup any static variables allocated for all registered value
596-
sets.
597-
*/
598-
static void cleanupValueSets();
599-
/**
600-
Cleanup any static variables allocated for a value set.
601-
\param[in] mod Module associated with the value set.
602-
\param[in] pt Parameter type associated with the value set.
603-
\param[in] noChildren If true, child classes will not be cleaned
604-
up.
605-
*/
606-
static void cleanupValueSet(const MODULE& mod, const PARAM_TYPE& pt,
607-
const bool noChildren = false);
608594
private:
609595
static void _readParam(const std::string& fname,
610596
std::map<std::string, std::string>& inputs,

include/modules/ModuleBase.hpp

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ class ModuleBase : public VALUE_SET_STATIC_PARENT(T, U, ID, PARAM_TYPE_MOD) {
202202
static void _select(const bool x = true,
203203
const bool noChildren = false) {
204204
ParentClass::_select(x, noChildren);
205-
for (std::vector<ValueSetClass_t*>::const_iterator it = added_classes.begin();
205+
for (std::vector<ValueSetClassWrapper>::const_iterator it = added_classes.begin();
206206
it != added_classes.end(); it++)
207207
if (*it)
208208
(*it)->select(x, noChildren);
@@ -211,7 +211,7 @@ class ModuleBase : public VALUE_SET_STATIC_PARENT(T, U, ID, PARAM_TYPE_MOD) {
211211
static void _enableC3(const bool x = true,
212212
const bool noChildren = false) {
213213
ParentClass::_enableC3(x, noChildren);
214-
for (std::vector<ValueSetClass_t*>::const_iterator it = added_classes.begin();
214+
for (std::vector<ValueSetClassWrapper>::const_iterator it = added_classes.begin();
215215
it != added_classes.end(); it++)
216216
if (*it)
217217
(*it)->enableC3(x, noChildren);
@@ -221,7 +221,7 @@ class ModuleBase : public VALUE_SET_STATIC_PARENT(T, U, ID, PARAM_TYPE_MOD) {
221221
ParentClass::_reset(noChildren);
222222
if (ParentClass::child_classes.size() > 0)
223223
return;
224-
for (std::vector<ValueSetClass_t*>::const_iterator it = added_classes.begin();
224+
for (std::vector<ValueSetClassWrapper>::const_iterator it = added_classes.begin();
225225
it != added_classes.end(); it++)
226226
if (*it) {
227227
(*it)->reset(noChildren);
@@ -234,7 +234,7 @@ class ModuleBase : public VALUE_SET_STATIC_PARENT(T, U, ID, PARAM_TYPE_MOD) {
234234
*/
235235
template<typename C>
236236
static void addClass() {
237-
added_classes.push_back(new ValueSetClassType<C>());
237+
added_classes.emplace_back(new ValueSetClassType<C>());
238238
}
239239

240240
/**
@@ -247,20 +247,8 @@ class ModuleBase : public VALUE_SET_STATIC_PARENT(T, U, ID, PARAM_TYPE_MOD) {
247247
T::_initAddedClasses();
248248
}
249249

250-
/**
251-
Clean up the set of added classes.
252-
*/
253-
static void cleanupAddedClasses() {
254-
if (added_classes.empty()) return;
255-
for (std::size_t i = 0; i < added_classes.size(); i++) {
256-
delete added_classes[i];
257-
added_classes[i] = nullptr;
258-
}
259-
added_classes.clear();
260-
}
261-
262250
/** Wrappers for value set classes associated with this module */
263-
static std::vector<ValueSetClass_t*> added_classes;
251+
static std::vector<ValueSetClassWrapper> added_classes;
264252

265253
protected:
266254
ModuleBase() {}
@@ -383,20 +371,10 @@ class ModuleBase : public VALUE_SET_STATIC_PARENT(T, U, ID, PARAM_TYPE_MOD) {
383371
initAddedClasses();
384372
}
385373

386-
/** \copydoc ValueSetBase::_cleanupStaticMembers */
387-
static void _cleanupStaticMembers() {
388-
ParentClass::_cleanupStaticMembers();
389-
for (std::vector<ValueSetClass_t*>::const_iterator it = added_classes.begin();
390-
it != added_classes.end(); it++)
391-
if (*it)
392-
(*it)->cleanupStaticMembers();
393-
cleanupAddedClasses();
394-
}
395-
396374
};
397375

398376
template<class T, class U, MODULE ID>
399-
std::vector<ValueSetClass_t*> ModuleBase<T, U, ID>::added_classes = {};
377+
std::vector<ValueSetClassWrapper> ModuleBase<T, U, ID>::added_classes = {};
400378

401379
} // namespace modules
402380
} // namespace ePhotosynthesis

0 commit comments

Comments
 (0)