diff options
author | Maciej Piechotka <uzytkownik2@gmail.com> | 2014-03-01 22:09:07 +0100 |
---|---|---|
committer | Maciej Piechotka <uzytkownik2@gmail.com> | 2014-03-01 22:09:07 +0100 |
commit | 3c0130ed4f7fe82c477d550846712f1930b6e7bc (patch) | |
tree | 2eecc55c207e9fe9570c1f7d2cc3138ce04cab66 /gee | |
parent | eed6c917cfc42a2cf880a08100420ab71d365046 (diff) | |
download | libgee-3c0130ed4f7fe82c477d550846712f1930b6e7bc.tar.gz |
Fix case of releasing lock-free resources during the local cleanup
Diffstat (limited to 'gee')
-rw-r--r-- | gee/hazardpointer.vala | 28 |
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 |