[libgee] 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] Fix case of releasing lock-free resources during the global cleanup
- Date: Sat, 1 Mar 2014 22:53:00 +0000 (UTC)
commit eed6c917cfc42a2cf880a08100420ab71d365046
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 | 31 ++++++++++++++++++++++++-------
1 files changed, 24 insertions(+), 7 deletions(-)
---
diff --git a/gee/hazardpointer.vala b/gee/hazardpointer.vala
index 7513751..937e08a 100644
--- a/gee/hazardpointer.vala
+++ b/gee/hazardpointer.vala
@@ -452,15 +452,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;
@@ -469,6 +476,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.
*/
@@ -482,21 +495,25 @@ public class Gee.HazardPointer<G> { // FIXME: Make it a struct
_queue = new LinkedList<ArrayList<FreeNode *>> ();
// Hack to not lie about successfull setting policy
policy = AtomicInt.add (ref release_policy, (int)(1 << (sizeof(int) *
8 - 1)));
- _global_to_free = new ArrayList<FreeNode *> ();
start ((ReleasePolicy) policy);
}
_queue_mutex.unlock ();
}
}
- 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]