[libgee] Fixes to ConcurrentList
- From: Maciej Marcin Piechotka <mpiechotka src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgee] Fixes to ConcurrentList
- Date: Mon, 6 Aug 2012 02:57:16 +0000 (UTC)
commit ddf32ef55e79042c28cad070e854d8f47fab8089
Author: Maciej Piechotka <uzytkownik2 gmail com>
Date: Sun Aug 5 19:51:30 2012 -0700
Fixes to ConcurrentList
- Fix using of freed memory in hazard pointers
- Remove memory leak on freeing node in debug build
- Set release policy to main loop by default
- Re-enable the ConcurrentList tests
gee/concurrentlist.vala | 7 +++++--
gee/hazardpointer.vala | 17 ++++++++++-------
tests/testconcurrentlist.vala | 6 ++++++
tests/testmain.vala | 2 +-
4 files changed, 22 insertions(+), 10 deletions(-)
---
diff --git a/gee/concurrentlist.vala b/gee/concurrentlist.vala
index 6d8e468..03d14bb 100644
--- a/gee/concurrentlist.vala
+++ b/gee/concurrentlist.vala
@@ -401,8 +401,11 @@ public class Gee.ConcurrentList<G> : AbstractList<G> {
HazardPointer.set_pointer<Node<G>?> (&_succ, null, 3);
HazardPointer.set_pointer<Node<G>?> (&_backlink, null);
#if DEBUG
- G? old_data = HazardPointer.exchange_pointer (&_data, null);
- stderr.printf (" Freeing node %p (with data %p)\n", this, old_data);
+ HazardPointer<G?>? old_data = HazardPointer.exchange_hazard_pointer (&_data, null);
+ stderr.printf (" Freeing node %p (with data %p)\n", this, old_data != null ? old_data.get() : null);
+ if (old_data != null) {
+ old_data.release (HazardPointer.get_destroy_notify<G?> ());
+ }
#else
HazardPointer.set_pointer<G> (&_data, null);
#endif
diff --git a/gee/hazardpointer.vala b/gee/hazardpointer.vala
index da0d8a8..d6dd7d1 100644
--- a/gee/hazardpointer.vala
+++ b/gee/hazardpointer.vala
@@ -164,8 +164,10 @@ public class Gee.HazardPointer<G> { // FIXME: Make it a struct
*/
public static void set_pointer<G> (G **aptr, owned G? new_ptr, size_t mask = 0, size_t new_mask = 0) {
HazardPointer<G>? ptr = exchange_hazard_pointer<G> (aptr, new_ptr, mask, new_mask, null);
- if (ptr != null)
- ptr.release (get_destroy_notify<G> ());
+ if (ptr != null) {
+ DestroyNotify<G> notify = get_destroy_notify<G> ();
+ ptr.release ((owned)notify);
+ }
}
/**
@@ -200,7 +202,8 @@ public class Gee.HazardPointer<G> { // FIXME: Make it a struct
void *old_rptr = (void *)((size_t)(old_ptr) | (mask & old_mask));
bool success = AtomicPointer.compare_and_exchange((void **)aptr, old_rptr, new_rptr);
if (success) {
- Context.get_current_context ()->release_ptr (old_ptr, get_destroy_notify<G> ());
+ DestroyNotify<G> notify = get_destroy_notify<G> ();
+ Context.get_current_context ()->release_ptr (old_ptr, (owned)notify);
} else if (new_ptr != null) {
delete new_ptr;
}
@@ -226,10 +229,10 @@ public class Gee.HazardPointer<G> { // FIXME: Make it a struct
*
* @param notify method freeing object
*/
- public void release (DestroyNotify notify) {
+ public void release (owned DestroyNotify notify) {
unowned G item = _node[false];
_node.set (null);
- Context.get_current_context ()->release_ptr (item, notify);
+ Context.get_current_context ()->release_ptr (item, (owned)notify);
}
/**
@@ -600,10 +603,10 @@ public class Gee.HazardPointer<G> { // FIXME: Make it a struct
/**
* Add pointer to freed array.
*/
- internal inline void release_ptr (void *ptr, DestroyNotify notify) {
+ internal inline void release_ptr (void *ptr, owned DestroyNotify notify) {
FreeNode *node = new FreeNode ();
node->pointer = ptr;
- node->destroy_notify = notify;
+ node->destroy_notify = (owned)notify;
_to_free.add (node);
if (_to_free.size >= THRESHOLD)
HazardPointer.try_free (_to_free);
diff --git a/tests/testconcurrentlist.vala b/tests/testconcurrentlist.vala
index 3bc5039..38b550f 100644
--- a/tests/testconcurrentlist.vala
+++ b/tests/testconcurrentlist.vala
@@ -28,11 +28,17 @@ public class ConcurrentListTests : ListTests {
}
public override void set_up () {
+ if (!policy_set) {
+ HazardPointer.set_release_policy(HazardPointer.ReleasePolicy.MAIN_LOOP);
+ policy_set = true;
+ }
test_collection = new Gee.ConcurrentList<string> ();
}
public override void tear_down () {
test_collection = null;
}
+
+ private static bool policy_set = false;
}
diff --git a/tests/testmain.vala b/tests/testmain.vala
index f05ae4d..20068e4 100644
--- a/tests/testmain.vala
+++ b/tests/testmain.vala
@@ -26,7 +26,7 @@ void main (string[] args) {
TestSuite.get_root ().add_suite (new ArrayListTests ().get_suite ());
TestSuite.get_root ().add_suite (new ArrayQueueTests ().get_suite ());
- //TestSuite.get_root ().add_suite (new ConcurrentListTests ().get_suite ());
+ TestSuite.get_root ().add_suite (new ConcurrentListTests ().get_suite ());
TestSuite.get_root ().add_suite (new FunctionsTests ().get_suite ());
TestSuite.get_root ().add_suite (new HashMapTests ().get_suite ());
TestSuite.get_root ().add_suite (new HashMultiMapTests ().get_suite ());
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]