[libgee] Always evaluate in when_done
- From: Maciej Marcin Piechotka <mpiechotka src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgee] Always evaluate in when_done
- Date: Tue, 9 Jul 2013 18:28:18 +0000 (UTC)
commit 9031c1ee9e5b9ed61472e6c81503177543df5dbc
Author: Maciej Piechotka <uzytkownik2 gmail com>
Date: Mon Jul 8 02:32:34 2013 +0200
Always evaluate in when_done
gee/flatmapfuture.vala | 97 +++++++++++++++++++++++++++-----------------
gee/future.vala | 2 +
gee/mapfuture.vala | 105 +++++++++++++++++++++++------------------------
3 files changed, 113 insertions(+), 91 deletions(-)
---
diff --git a/gee/flatmapfuture.vala b/gee/flatmapfuture.vala
index 5df8149..20020ec 100644
--- a/gee/flatmapfuture.vala
+++ b/gee/flatmapfuture.vala
@@ -24,10 +24,10 @@ internal class Gee.FlatMapFuture<A, G> : Object, Future<A> {
public FlatMapFuture (Future<G> base_future, Future.FlatMapFunc<A, G> func) {
_base = base_future;
_func = func;
- _base.when_done (() => {
+ _base.when_done ((val) => {
_mutex.lock ();
if (_progress == Progress.INIT) {
- go_map ();
+ go_map (val);
} else {
_mutex.unlock ();
}
@@ -43,52 +43,75 @@ internal class Gee.FlatMapFuture<A, G> : Object, Future<A> {
}
}
- public unowned G wait () {
- unowned Future<A> ret_future;
+ public unowned A wait () {
_mutex.lock ();
- switch (_progress) {
- case Progress.INIT:
- ret_future = go_map ();
- break;
- case Progress.PROGRESS:
- _cond.wait (_mutex);
+ Progress progress = _progress;
+ if (progress == Progress.INIT) {
+ Future<G> base_future = _base;
_mutex.unlock ();
- ret_future = _mapped;
- break;
- case Progress.READY:
+ base_future.wait ();
+ _mutex.lock ();
+ progress = Progress.PROGRESS;
+ }
+ if (progress == Progress.PROGRESS) {
+ _cond.wait (_mutex);
+ progress = Progress.READY;
+ }
+ if (progress == Progress.READY) {
_mutex.unlock ();
- ret_future = _mapped;
- break;
- default:
- assert_not_reached ();
+ return _mapped.wait ();
}
- return ret_future.wait ();
+ assert_not_reached ();
}
public unowned bool wait_until (int64 end_time, out unowned G? value = null) {
- bool ret_value;
_mutex.lock ();
- switch (_progress) {
- case Progress.INIT:
- ret_value = go_map ().wait_until (end_time, out value);
- break;
- case Progress.PROGRESS:
- if (ret_value = _cond.wait_until (_mutex, end_time)) {
- _mutex.unlock ();
- ret_value = _mapped.wait_until (end_time, out value);
- } else {
+ Progress progress = _progress;
+ if (progress == Progress.INIT) {
+ Future<G> base_future = _base;
+ _mutex.unlock ();
+ if (!base_future.wait_until (end_time)) {
+ return false;
+ }
+ _mutex.lock ();
+ progress = Progress.PROGRESS;
+ }
+ if (progress == Progress.PROGRESS) {
+ if (!_cond.wait_until (_mutex, end_time)) {
_mutex.unlock ();
- value = null;
+ return false;
}
- break;
- case Progress.READY:
+ progress = Progress.READY;
+ }
+ if (progress == Progress.READY) {
+ _mutex.unlock ();
+ return _mapped.wait_until (end_time, out value);
+ }
+ assert_not_reached ();
+ }
+
+ public async unowned A wait_async () {
+ _mutex.lock ();
+ Progress progress = _progress;
+ if (progress == Progress.INIT) {
+ Future<G> base_future = _base;
+ _mutex.unlock ();
+ yield base_future.wait_async ();
+ _mutex.lock ();
+ progress = Progress.PROGRESS;
+ }
+ if (progress == Progress.PROGRESS) {
+ unowned A result = null;
+ _when_done += Future.WhenDoneArrayElement<G>((res) => {
+ wait_async.callback ();
+ });
+ progress = Progress.READY;
+ }
+ if (progress == Progress.READY) {
_mutex.unlock ();
- ret_value = _mapped.wait_until (end_time, out value);
- break;
- default:
- assert_not_reached ();
+ return yield _mapped.wait_async ();
}
- return ret_value;
+ assert_not_reached ();
}
public void when_done (Future.WhenDoneFunc<A> func) {
@@ -102,7 +125,7 @@ internal class Gee.FlatMapFuture<A, G> : Object, Future<A> {
}
}
- private unowned Future<A> go_map () {
+ private unowned Future<A> go_map (G val) {
_progress = Progress.PROGRESS;
_mutex.unlock ();
diff --git a/gee/future.vala b/gee/future.vala
index 5cb2130..1747795 100644
--- a/gee/future.vala
+++ b/gee/future.vala
@@ -124,6 +124,8 @@ public interface Gee.Future<G> : Object {
*/
public abstract void when_done (WhenDoneFunc<G> func);
+ public delegate A MapFunc<A, G> (G value);
+
/**
* Maps a future value to another value by a function and returns the
* another value in future.
diff --git a/gee/mapfuture.vala b/gee/mapfuture.vala
index 1bc13a4..3d3bb8d 100644
--- a/gee/mapfuture.vala
+++ b/gee/mapfuture.vala
@@ -21,13 +21,13 @@
*/
internal class Gee.MapFuture<A, G> : Object, Future<A> {
- public MapFuture (Future<G> future_base, MapFunc<A, G> func) {
+ public MapFuture (Future<G> future_base, Future.MapFunc<A, G> func) {
_base = future_base;
_func = func;
- _base.when_done (() => {
+ _base.when_done ((val) => {
_mutex.lock ();
if (_progress == Progress.INIT) {
- go_map ();
+ go_map (val);
} else {
_mutex.unlock ();
}
@@ -37,87 +37,84 @@ internal class Gee.MapFuture<A, G> : Object, Future<A> {
public bool ready {
get {
_mutex.lock ();
- bool locked = _progress == Progress.READY;
+ bool result = _progress == Progress.READY;
_mutex.unlock ();
- return locked;
+ return result;
}
}
public unowned A wait () {
- unowned A ret_value;
_mutex.lock ();
- switch (_progress) {
- case Progress.INIT:
- ret_value = go_map ();
- break;
- case Progress.PROGRESS:
- _cond.wait (_mutex);
+ Progress progress = _progress;
+ if (progress == Progress.INIT) {
+ Future<G> base_future = _base;
_mutex.unlock ();
- ret_value = _value;
- break;
- case Progress.READY:
+ base_future.wait ();
+ _mutex.lock ();
+ progress = Progress.PROGRESS;
+ }
+ if (progress == Progress.PROGRESS) {
+ _cond.wait (_mutex);
+ progress = Progress.READY;
+ }
+ if (progress == Progress.READY) {
_mutex.unlock ();
- ret_value = _value;
- break;
- default:
- assert_not_reached ();
+ return _value;
}
- return ret_value;
+ assert_not_reached ();
}
- public unowned bool wait_until (int64 end_time, out unowned G? value = null) {
- bool ret_value;
+ public unowned bool wait_until (int64 end_time, out unowned A? value = null) {
_mutex.lock ();
- switch (_progress) {
- case Progress.INIT:
- if (!_base.wait_until (end_time)) {
- _mutex.unlock ();
+ Progress progress = _progress;
+ if (progress == Progress.INIT) {
+ Future<G> base_future = _base;
+ _mutex.unlock ();
+ if (!base_future.wait_until (end_time)) {
return false;
}
- value = go_map ();
- ret_value = true;
- break;
- case Progress.PROGRESS:
- if (ret_value = _cond.wait_until (_mutex, end_time)) {
- _mutex.unlock ();
- value = _value;
- } else {
+ _mutex.lock ();
+ progress = Progress.PROGRESS;
+ }
+ if (progress == Progress.PROGRESS) {
+ if (!_cond.wait_until (_mutex, end_time)) {
_mutex.unlock ();
+ return false;
}
- break;
- case Progress.READY:
+ progress = Progress.READY;
+ }
+ if (progress == Progress.READY) {
_mutex.unlock ();
value = _value;
- ret_value = true;
- break;
- default:
- assert_not_reached ();
+ return true;
}
- return ret_value;
+ assert_not_reached ();
}
public async unowned A wait_async () {
- unowned G g = yield _base.wait_async ();
_mutex.lock ();
- switch (_progress) {
- case Progress.INIT:
- go_map ();
- return _value;
- case Progress.PROGRESS:
+ Progress progress = _progress;
+ if (progress == Progress.INIT) {
+ Future<G> base_future = _base;
+ _mutex.unlock ();
+ yield base_future.wait_async ();
+ _mutex.lock ();
+ progress = Progress.PROGRESS;
+ }
+ if (progress == Progress.PROGRESS) {
unowned A result = null;
_when_done += Future.WhenDoneArrayElement<G>((res) => {
- result = res;
wait_async.callback ();
});
_mutex.unlock ();
yield;
return _value;
- case Progress.READY:
+ }
+ if (progress == Progress.READY) {
_mutex.unlock ();
return _value;
- default:
- assert_not_reached ();
}
+ assert_not_reached ();
}
public void when_done (Future.WhenDoneFunc<A> func) {
@@ -131,11 +128,11 @@ internal class Gee.MapFuture<A, G> : Object, Future<A> {
}
}
- private inline unowned A go_map () {
+ private inline unowned A go_map (G val) {
_progress = Progress.PROGRESS;
_mutex.unlock ();
- A tmp_value = _func (_base.value);
+ A tmp_value = _func (val);
unowned A value = tmp_value;
_mutex.lock ();
@@ -162,7 +159,7 @@ internal class Gee.MapFuture<A, G> : Object, Future<A> {
private Mutex _mutex = Mutex ();
private Cond _cond = Cond ();
private Future<G> _base;
- private MapFunc<A, G> _func;
+ private Future.MapFunc<A, G> _func;
private A _value;
private Progress _progress = Progress.INIT;
private Future.WhenDoneArrayElement<G>[]? _when_done = new Future.WhenDoneArrayElement<G>[0];
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]