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

Enea Zaffanella zaffanella at cs.unipr.it
Thu Nov 26 12:40:09 CET 2015


Module: ppl/ppl
Branch: devel
Commit: cc65f4c19ad8d6e8005e76605c4dd8f62679c0eb
URL:    http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=cc65f4c19ad8d6e8005e76605c4dd8f62679c0eb

Author: Enea Zaffanella <zaffanella at 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
 




More information about the PPL-devel mailing list