summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/actors/scala/actors/Future.scala37
-rw-r--r--test/files/jvm/future-alarm.check20
-rw-r--r--test/files/jvm/future-alarm.scala16
3 files changed, 62 insertions, 11 deletions
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")
+ }
+ }
+}