summaryrefslogtreecommitdiff
path: root/src/actors
diff options
context:
space:
mode:
authorPhilipp Haller <hallerp@gmail.com>2009-12-21 19:28:18 +0000
committerPhilipp Haller <hallerp@gmail.com>2009-12-21 19:28:18 +0000
commit169b05aa40915fd805d29a40f95877402320cca3 (patch)
tree8c885ee1b2873a8ce00aeb2996d1021f2ab29b1f /src/actors
parenta326f40dbf25e50976d17a3a90bdd2dc5e37a87e (diff)
downloadscala-169b05aa40915fd805d29a40f95877402320cca3.tar.gz
scala-169b05aa40915fd805d29a40f95877402320cca3.tar.bz2
scala-169b05aa40915fd805d29a40f95877402320cca3.zip
closed #1449. review by community.
Diffstat (limited to 'src/actors')
-rw-r--r--src/actors/scala/actors/Future.scala49
1 files changed, 40 insertions, 9 deletions
diff --git a/src/actors/scala/actors/Future.scala b/src/actors/scala/actors/Future.scala
index c3c12915e9..ebb0489d88 100644
--- a/src/actors/scala/actors/Future.scala
+++ b/src/actors/scala/actors/Future.scala
@@ -10,6 +10,8 @@
package scala.actors
+import scala.actors.scheduler.DaemonScheduler
+
/** A `Future[T]` is a function of arity 0 that returns
* a value of type `T`.
* Applying a future blocks the current actor (`Actor.self`)
@@ -21,6 +23,7 @@ package scala.actors
* @author Philipp Haller
*/
abstract class Future[+T](val inputChannel: InputChannel[T]) extends Responder[T] with Function0[T] {
+ @volatile
private[actors] var fvalue: Option[Any] = None
private[actors] def fvalueTyped = fvalue.get.asInstanceOf[T]
@@ -37,7 +40,7 @@ abstract class Future[+T](val inputChannel: InputChannel[T]) extends Responder[T
def isSet: Boolean
}
-/** The <code>Futures</code> object contains methods that operate on futures.
+/** The `Futures` object contains methods that operate on futures.
*
* @author Philipp Haller
*/
@@ -45,6 +48,39 @@ object Futures {
private case object Eval
+ private class FutureActor[T](fun: () => T, channel: Channel[T])
+ extends Future[T](channel) with DaemonActor {
+
+ def isSet = !fvalue.isEmpty
+
+ def apply(): T = {
+ if (fvalue.isEmpty)
+ this !? Eval
+ fvalueTyped
+ }
+
+ def respond(k: T => Unit) {
+ if (isSet) k(fvalueTyped)
+ else {
+ val ft = this !! Eval
+ ft.inputChannel.react {
+ case _ => k(fvalueTyped)
+ }
+ }
+ }
+
+ def act() {
+ val res = fun()
+ fvalue = Some(res)
+ channel ! res
+ Actor.loop {
+ Actor.react {
+ case Eval => Actor.reply()
+ }
+ }
+ }
+ }
+
/** Arranges for the asynchronous execution of `body`,
* returning a future representing the result.
*
@@ -53,15 +89,10 @@ object Futures {
* computation
*/
def future[T](body: => T): Future[T] = {
- val a = new DaemonActor {
- def act() {
- Actor.react {
- case Eval => Actor.reply(body)
- }
- }
- }
+ val c = new Channel[T](Actor.self(DaemonScheduler))
+ val a = new FutureActor[T](() => body, c)
a.start()
- a !! (Eval, { case any => any.asInstanceOf[T] })
+ a
}
/** Creates a future that resolves after a given time span.