[libgee/0.12] Fix case of releasing lock-free resources during the global cleanup
- From: Maciej Marcin Piechotka <mpiechotka src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgee/0.12] Fix case of releasing lock-free resources during the global cleanup
- Date: Mon, 3 Mar 2014 23:08:03 +0000 (UTC)
commit 98f4edcd9ecd3e329c0e77d6fdba1c49602a26e2
Author: Maciej Piechotka <uzytkownik2 gmail com>
Date: Sat Mar 1 21:58:41 2014 +0100
Fix case of releasing lock-free resources during the global cleanup
gee/hazardpointer.vala | 30 ++++++++++++++++++++++++------
1 files changed, 24 insertions(+), 6 deletions(-)
---
diff --git a/gee/hazardpointer.vala b/gee/hazardpointer.vala
index 81a9306..f3238d2 100644
--- a/gee/hazardpointer.vala
+++ b/gee/hazardpointer.vala
@@ -450,15 +450,22 @@ public class Gee.HazardPointer<G> { // FIXME: Make it a struct
switch (self) {
case HELPER_THREAD:
new Thread<bool> ("<<libgee hazard pointer>>", () => {
+ Context ctx = new Context (Policy.TRY_FREE);
while (true) {
Thread.yield ();
- attempt_free ();
+ pull_from_queue (ctx._to_free, ctx._to_free.is_empty);
+ ctx.try_free ();
}
});
break;
case MAIN_LOOP:
+ _global_to_free = new ArrayList<FreeNode *> ();
Idle.add (() => {
- attempt_free ();
+ Context ctx = new Context (Policy.TRY_FREE);
+ swap (ref _global_to_free, ref ctx._to_free);
+ pull_from_queue (ctx._to_free, false);
+ ctx.try_free ();
+ swap (ref _global_to_free, ref ctx._to_free);
return true;
}, Priority.LOW);
break;
@@ -467,6 +474,12 @@ public class Gee.HazardPointer<G> { // FIXME: Make it a struct
}
}
+ private static void swap<T>(ref T a, ref T b) {
+ T tmp = (owned)a;
+ a = (owned)b;
+ b = (owned)tmp;
+ }
+
/**
* Ensures that helper methods are started.
*/
@@ -486,14 +499,19 @@ public class Gee.HazardPointer<G> { // FIXME: Make it a struct
}
}
- private static inline void attempt_free () {
- if (_queue_mutex.trylock ()) {
+ private static inline void pull_from_queue (Collection<FreeNode *> to_free, bool do_lock) {
+ bool locked = do_lock;
+ if (do_lock) {
+ _queue_mutex.lock ();
+ } else {
+ locked = _queue_mutex.trylock ();
+ }
+ if (locked) {
Collection<ArrayList<FreeNode *>> temp = new ArrayList<ArrayList<FreeNode *>>
();
_queue.drain (temp);
_queue_mutex.unlock ();
- temp.foreach ((x) => {_global_to_free.add_all (x); return true;});
+ temp.foreach ((x) => {to_free.add_all (x); return true;});
}
- try_free (_global_to_free);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]