[GIT] ppl/ppl(devel): Avoid a memory leak due to the global list of dirty temporaries.

Module: ppl/ppl Branch: devel Commit: cc65f4c19ad8d6e8005e76605c4dd8f62679c0eb URL: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=cc65f4c19ad8d...
Author: Enea Zaffanella zaffanella@cs.unipr.it Date: Thu Nov 26 12:31:01 2015 +0100
Avoid a memory leak due to the global list of dirty temporaries.
The memory leak was not causing a real problem, in that the list of dirty temporaries is meant to survive up to the end of the process. However, it could cause a problem if/when the library is extended to become multi-thread safe, since in such a scenario it is meaningful to have a list of dirty temporaries for each thread (to be released on thread exit).
---
src/Temp_defs.hh | 14 +++++++++++++- src/Temp_inlines.hh | 23 ++++++++++++++++++----- src/Temp_templates.hh | 8 +++++++- 3 files changed, 38 insertions(+), 7 deletions(-)
diff --git a/src/Temp_defs.hh b/src/Temp_defs.hh index 9c16020..e272397 100644 --- a/src/Temp_defs.hh +++ b/src/Temp_defs.hh @@ -51,8 +51,20 @@ private: //! Pointer to the next item in the free list. Temp_Item* next;
+ class Free_List { + public: + Free_List(); + ~Free_List(); + Temp_Item* head_ptr; + private: + Free_List(const Free_List&); // Not implemented. + Free_List& operator=(const Free_List&); // Not implemented. + }; // class Free_List + + friend class Free_List; + //! Head of the free list. - static Temp_Item* free_list_head; + static Temp_Item*& free_list_ref();
//! Default constructor. Temp_Item(); diff --git a/src/Temp_inlines.hh b/src/Temp_inlines.hh index 607fc0d..f357b3e 100644 --- a/src/Temp_inlines.hh +++ b/src/Temp_inlines.hh @@ -41,11 +41,24 @@ Temp_Item<T>::item() { }
template <typename T> +inline +Temp_Item<T>::Free_List::Free_List() + : head_ptr(0) { +} + +template <typename T> +inline Temp_Item<T>*& +Temp_Item<T>::free_list_ref() { + static Free_List free_list; + return free_list.head_ptr; +} + +template <typename T> inline Temp_Item<T>& Temp_Item<T>::obtain() { - if (free_list_head != 0) { - Temp_Item* const p = free_list_head; - free_list_head = free_list_head->next; + Temp_Item* const p = free_list_ref(); + if (p != 0) { + free_list_ref() = p->next; return *p; } else { @@ -56,8 +69,8 @@ Temp_Item<T>::obtain() { template <typename T> inline void Temp_Item<T>::release(Temp_Item& p) { - p.next = free_list_head; - free_list_head = &p; + p.next = free_list_ref(); + free_list_ref() = &p; }
template <typename T> diff --git a/src/Temp_templates.hh b/src/Temp_templates.hh index 09f6b11..40c65af 100644 --- a/src/Temp_templates.hh +++ b/src/Temp_templates.hh @@ -27,7 +27,13 @@ site: http://bugseng.com/products/ppl/ . */ namespace Parma_Polyhedra_Library {
template <typename T> -Temp_Item<T>* Temp_Item<T>::free_list_head = 0; +Temp_Item<T>::Free_List::~Free_List() { + while (head_ptr != 0) { + Temp_Item* const p = head_ptr; + head_ptr = head_ptr->next; + delete p; + } +}
} // namespace Parma_Polyhedra_Library
participants (1)
-
Enea Zaffanella