summaryrefslogtreecommitdiff
path: root/gee
diff options
context:
space:
mode:
authorMaciej Piechotka <uzytkownik2@gmail.com>2014-03-01 22:09:07 +0100
committerMaciej Piechotka <uzytkownik2@gmail.com>2014-03-01 22:09:07 +0100
commit3c0130ed4f7fe82c477d550846712f1930b6e7bc (patch)
tree2eecc55c207e9fe9570c1f7d2cc3138ce04cab66 /gee
parenteed6c917cfc42a2cf880a08100420ab71d365046 (diff)
downloadlibgee-3c0130ed4f7fe82c477d550846712f1930b6e7bc.tar.gz
Fix case of releasing lock-free resources during the local cleanup
Diffstat (limited to 'gee')
-rw-r--r--gee/hazardpointer.vala28
1 files changed, 13 insertions, 15 deletions
diff --git a/gee/hazardpointer.vala b/gee/hazardpointer.vala
index 937e08a..22aca16 100644
--- a/gee/hazardpointer.vala
+++ b/gee/hazardpointer.vala
@@ -402,33 +402,34 @@ public class Gee.HazardPointer<G> { // FIXME: Make it a struct
* @param to_free List containing elements to free.
* @return Non-empty list of not freed elements or ``null`` if all elements have been disposed.
*/
- internal ArrayList<FreeNode *>? perform (owned ArrayList<FreeNode *> to_free) {
+ internal bool perform (ref ArrayList<FreeNode *> to_free) {
switch (this.to_concrete ()) {
case TRY_FREE:
- return try_free (to_free) ? (owned) to_free : null;
+ return try_free (to_free);
case FREE:
while (try_free (to_free)) {
Thread.yield ();
}
- return null;
+ break;
case TRY_RELEASE:
ReleasePolicy.ensure_start ();
if (_queue_mutex.trylock ()) {
_queue.offer ((owned) to_free);
_queue_mutex.unlock ();
- return null;
+ return true;
} else {
- return (owned) to_free;
+ return false;
}
case RELEASE:
ReleasePolicy.ensure_start ();
_queue_mutex.lock ();
_queue.offer ((owned) to_free);
_queue_mutex.unlock ();
- return null;
+ return true;
default:
assert_not_reached ();
}
+ return false;
}
}
@@ -561,15 +562,12 @@ public class Gee.HazardPointer<G> { // FIXME: Make it a struct
int size = _to_free.size;
bool clean_parent = false;
if (size > 0) {
- ArrayList<FreeNode *>? remaining;
- if (_parent == null || size >= THRESHOLD)
- remaining = _policy.perform ((owned) _to_free);
- else
- remaining = (owned) _to_free;
- if (remaining != null) {
- assert (_parent != null);
- _parent->_to_free.add_all (remaining);
- clean_parent = true;
+ if (_parent == null || size >= THRESHOLD) {
+ if (!_policy.perform (ref _to_free)) {
+ assert (_parent != null && _to_free != null);
+ _parent->_to_free.add_all (_to_free);
+ clean_parent = true;
+ }
}
}
#if DEBUG