From: Nick Holland Date: Mon, 27 Feb 2017 15:11:26 +0000 (+0000) Subject: [3.0] Fix Message Buffer leak and added DEBUG_ASSERT for leaking nodes X-Git-Tag: accepted/tizen/3.0/common/20170323.155250~3 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-core.git;a=commitdiff_plain;h=a93869f74b472de57c6f383ad9d4f5b56c01b210 [3.0] Fix Message Buffer leak and added DEBUG_ASSERT for leaking nodes Current message queue is not cleared when update is destroyed This is 1 cause of Node leak. Second cause of Node leak is InstallRootMessage passes a layer as a raw pointer. If update doesn't run ( doesn't run in the test cases), then we leak the layer (node). Also added DEBUG_ASSERT to check for leaking scene graph Nodes Change-Id: Ibfbb73ee840cbeaf33104da6769945cf9b3aafbc --- diff --git a/dali/internal/update/manager/update-manager.h b/dali/internal/update/manager/update-manager.h index 9a285d3..1147f9f 100644 --- a/dali/internal/update/manager/update-manager.h +++ b/dali/internal/update/manager/update-manager.h @@ -665,7 +665,8 @@ private: inline void InstallRootMessage( UpdateManager& manager, Layer& root, bool systemLevel ) { - typedef MessageValue2< UpdateManager, Layer*, bool > LocalType; + // Message has ownership of Layer while in transit from event -> update + typedef MessageValue2< UpdateManager, OwnerPointer, bool > LocalType; // Reserve some memory inside the message queue unsigned int* slot = manager.ReserveMessageSlot( sizeof( LocalType ) ); @@ -676,6 +677,7 @@ inline void InstallRootMessage( UpdateManager& manager, Layer& root, bool system inline void AddNodeMessage( UpdateManager& manager, Node& node ) { + // Message has ownership of Node while in transit from event -> update typedef MessageValue1< UpdateManager, OwnerPointer > LocalType; // Reserve some memory inside the message queue diff --git a/dali/internal/update/nodes/node.cpp b/dali/internal/update/nodes/node.cpp index ebf6565..5c09326 100644 --- a/dali/internal/update/nodes/node.cpp +++ b/dali/internal/update/nodes/node.cpp @@ -30,6 +30,16 @@ namespace //Unnamed namespace //Memory pool used to allocate new nodes. Memory used by this pool will be released when process dies // or DALI library is unloaded Dali::Internal::MemoryPoolObjectAllocator gNodeMemoryPool; +#ifdef DEBUG_ENABLED +// keep track of nodes created / deleted, to ensure we have 0 when the process exits or DALi library is unloaded +int gNodeCount =0; + +// Called when the process is about to exit, Node count should be zero at this point. +void __attribute__ ((destructor)) ShutDown(void) +{ +DALI_ASSERT_DEBUG( (gNodeCount == 0) && "Node memory leak"); +} +#endif } namespace Dali @@ -100,6 +110,11 @@ Node::Node() { mUniformMapChanged[0] = 0u; mUniformMapChanged[1] = 0u; + +#ifdef DEBUG_ENABLED + gNodeCount++; +#endif + } Node::~Node() @@ -108,6 +123,10 @@ Node::~Node() { mTransformManager->RemoveTransform(mTransformId); } + +#ifdef DEBUG_ENABLED + gNodeCount--; +#endif } void Node::OnDestroy() diff --git a/dali/internal/update/nodes/scene-graph-layer.cpp b/dali/internal/update/nodes/scene-graph-layer.cpp index 4519171..46bb14c 100644 --- a/dali/internal/update/nodes/scene-graph-layer.cpp +++ b/dali/internal/update/nodes/scene-graph-layer.cpp @@ -113,6 +113,15 @@ void Layer::ClearRenderables() } // namespace SceneGraph +template <> +void OwnerPointer::Reset() +{ + if( mObject != NULL ) + { + Dali::Internal::SceneGraph::Node::Delete( mObject ); + mObject = NULL; + } +} } // namespace Internal } // namespace Dali diff --git a/dali/internal/update/nodes/scene-graph-layer.h b/dali/internal/update/nodes/scene-graph-layer.h index d3ea452..f56bdd3 100644 --- a/dali/internal/update/nodes/scene-graph-layer.h +++ b/dali/internal/update/nodes/scene-graph-layer.h @@ -332,6 +332,10 @@ inline void SetDepthTestDisabledMessage( EventThreadServices& eventThreadService } // namespace SceneGraph +// Template specialisation for OwnerPointer, because delete is protected +template <> +void OwnerPointer::Reset(); + } // namespace Internal } // namespace Dali diff --git a/dali/internal/update/queue/update-message-queue.cpp b/dali/internal/update/queue/update-message-queue.cpp index 0e361f7..f6f7193 100644 --- a/dali/internal/update/queue/update-message-queue.cpp +++ b/dali/internal/update/queue/update-message-queue.cpp @@ -76,7 +76,11 @@ struct MessageQueue::Impl ~Impl() { // Delete the current buffer - delete currentMessageBuffer; + if( currentMessageBuffer ) + { + DeleteBufferContents( currentMessageBuffer ); + delete currentMessageBuffer; + } // Delete the unprocessed buffers const MessageBufferIter processQueueEndIter = processQueue.end();