From 5df06dc8dafef7f76b6783e7a473f30678c55d58 Mon Sep 17 00:00:00 2001 From: Philipp Haller Date: Tue, 2 Feb 2010 12:40:38 +0000 Subject: Closes #3009. --- src/actors/scala/actors/Future.scala | 37 +++++++++++++++++++++++++----------- test/files/jvm/future-alarm.check | 20 +++++++++++++++++++ test/files/jvm/future-alarm.scala | 16 ++++++++++++++++ 3 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 test/files/jvm/future-alarm.check create mode 100644 test/files/jvm/future-alarm.scala diff --git a/src/actors/scala/actors/Future.scala b/src/actors/scala/actors/Future.scala index ebb0489d88..cbdba8010e 100644 --- a/src/actors/scala/actors/Future.scala +++ b/src/actors/scala/actors/Future.scala @@ -46,11 +46,15 @@ abstract class Future[+T](val inputChannel: InputChannel[T]) extends Responder[T */ object Futures { + import scala.concurrent.SyncVar + private case object Eval - private class FutureActor[T](fun: () => T, channel: Channel[T]) + private class FutureActor[T](fun: SyncVar[T] => Unit, channel: Channel[T]) extends Future[T](channel) with DaemonActor { + import Actor._ + def isSet = !fvalue.isEmpty def apply(): T = { @@ -70,12 +74,17 @@ object Futures { } def act() { - val res = fun() - fvalue = Some(res) - channel ! res - Actor.loop { - Actor.react { - case Eval => Actor.reply() + val res = new SyncVar[T] + + { + fun(res) + } andThen { + fvalue = Some(res.get) + channel ! res.get + loop { + react { + case Eval => reply() + } } } } @@ -90,7 +99,7 @@ object Futures { */ def future[T](body: => T): Future[T] = { val c = new Channel[T](Actor.self(DaemonScheduler)) - val a = new FutureActor[T](() => body, c) + val a = new FutureActor[T](_.set(body), c) a.start() a } @@ -100,10 +109,16 @@ object Futures { * @param timespan the time span in ms after which the future resolves * @return the future */ - def alarm(timespan: Long) = future { - Actor.reactWithin(timespan) { - case TIMEOUT => {} + def alarm(timespan: Long): Future[Unit] = { + val c = new Channel[Unit](Actor.self(DaemonScheduler)) + val fun = (res: SyncVar[Unit]) => { + Actor.reactWithin(timespan) { + case TIMEOUT => res.set({}) + } } + val a = new FutureActor[Unit](fun, c) + a.start() + a } /** Waits for the first result returned by one of two diff --git a/test/files/jvm/future-alarm.check b/test/files/jvm/future-alarm.check new file mode 100644 index 0000000000..01a87d1c4c --- /dev/null +++ b/test/files/jvm/future-alarm.check @@ -0,0 +1,20 @@ +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK diff --git a/test/files/jvm/future-alarm.scala b/test/files/jvm/future-alarm.scala new file mode 100644 index 0000000000..0dda492741 --- /dev/null +++ b/test/files/jvm/future-alarm.scala @@ -0,0 +1,16 @@ +import scala.actors.Futures + +object Test { + def main(args: Array[String]) { + for (i <- 1 to 100000) { + Futures.alarm(0) + if (i % 10000 == 0) + println("OK") + } + for (_ <- 1 to 10) { + val ft = Futures.alarm(100) + ft() + println("OK") + } + } +} -- cgit v1.2.3