[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