Skip to content

Commit

Permalink
refactor(Placeholder): encapsulate SOO memory management and fix leak…
Browse files Browse the repository at this point in the history
…s; cf. #3297 #3514
  • Loading branch information
aleks-f committed Apr 14, 2022
1 parent c032c16 commit 65aa10b
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 36 deletions.
31 changes: 16 additions & 15 deletions Foundation/include/Poco/Any.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,20 @@ union Placeholder
static const unsigned int value = SizeV;
};

Placeholder()
Placeholder(): pHolder(0)
{
erase();
std::memset(holder, 0, sizeof(Placeholder));
}

~Placeholder()
{
if (!isLocal())
delete pHolder;
else
{
if (!isEmpty())
reinterpret_cast<PlaceholderT*>(holder)->~PlaceholderT();
}
}

void swap(Placeholder& other)
Expand All @@ -83,6 +94,7 @@ union Placeholder

void erase()
{
if (!isLocal()) delete pHolder;
std::memset(holder, 0, sizeof(Placeholder));
}

Expand All @@ -105,6 +117,7 @@ union Placeholder
template <typename T, typename V>
PlaceholderT* assignStack(const V& value)
{
erase();
new (reinterpret_cast<PlaceholderT*>(holder)) T(value);
setLocal(true);
return reinterpret_cast<PlaceholderT*>(holder);
Expand All @@ -113,6 +126,7 @@ union Placeholder
template <typename T, typename V>
PlaceholderT* assignHeap(const V& value)
{
erase();
pHolder = new T(value);
setLocal(false);
return pHolder;
Expand Down Expand Up @@ -217,13 +231,6 @@ class Any
/// Destructor. If Any is locally held, calls ValueHolder destructor;
/// otherwise, deletes the placeholder from the heap.
{
if (!empty())
{
if (_valueHolder.isLocal())
destruct();
else
delete content();
}
}

Any& swap(Any& other)
Expand All @@ -244,7 +251,6 @@ class Any
Any tmp(*this);
try
{
if (_valueHolder.isLocal()) destruct();
construct(other);
other = tmp;
}
Expand Down Expand Up @@ -372,11 +378,6 @@ class Any
_valueHolder.erase();
}

void destruct()
{
content()->~ValueHolder();
}

Placeholder<ValueHolder> _valueHolder;


Expand Down
15 changes: 1 addition & 14 deletions Foundation/include/Poco/Dynamic/Var.h
Original file line number Diff line number Diff line change
Expand Up @@ -661,21 +661,9 @@ class Foundation_API Var

void construct(const Var& other)
{
_placeholder.erase();
if (!other.isEmpty())
other.content()->clone(&_placeholder);
else
_placeholder.erase();
}

void destruct()
{
if (!isEmpty())
{
if (_placeholder.isLocal())
content()->~VarHolder();
else
delete content();
}
}

Placeholder<VarHolder> _placeholder;
Expand Down Expand Up @@ -712,7 +700,6 @@ inline void Var::swap(Var& other)
Var tmp(*this);
try
{
if (_placeholder.isLocal()) destruct();
construct(other);
other = tmp;
}
Expand Down
4 changes: 2 additions & 2 deletions Foundation/include/Poco/Dynamic/VarHolder.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,8 +307,8 @@ class Foundation_API VarHolder
(void)pVarHolder;
return new VarHolderImpl<T>(val);
#else
poco_check_ptr (pVarHolder);
return makeSOOHolder(pVarHolder, val);
poco_check_ptr (pVarHolder);
return makeSOOHolder(pVarHolder, val);
#endif
}

Expand Down
5 changes: 0 additions & 5 deletions Foundation/src/Var.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ Var::Var(const Var& other)

Var::~Var()
{
destruct();
}


Expand Down Expand Up @@ -330,8 +329,6 @@ void Var::empty()
delete _pHolder;
_pHolder = 0;
#else
if (_placeholder.isLocal()) this->~Var();
else delete content();
_placeholder.erase();
#endif
}
Expand All @@ -343,8 +340,6 @@ void Var::clear()
delete _pHolder;
_pHolder = 0;
#else
if (_placeholder.isLocal()) this->~Var();
else delete content();
_placeholder.erase();
#endif
}
Expand Down

0 comments on commit 65aa10b

Please sign in to comment.