From ed73e93b1064d551b4c3baa23b73c854d70e251b Mon Sep 17 00:00:00 2001 From: Philipp Haller Date: Fri, 16 Nov 2007 17:14:00 +0000 Subject: Fixed combinator bug. --- src/actors/scala/actors/Actor.scala | 93 ++++++++++------------------------ src/actors/scala/actors/Reaction.scala | 2 +- 2 files changed, 29 insertions(+), 66 deletions(-) diff --git a/src/actors/scala/actors/Actor.scala b/src/actors/scala/actors/Actor.scala index 0855866f0c..beae0652a5 100644 --- a/src/actors/scala/actors/Actor.scala +++ b/src/actors/scala/actors/Actor.scala @@ -15,11 +15,11 @@ import scala.compat.Platform /** * The Actor object provides functions for the definition of - * actors, as well as all actor operations, such as + * actors, as well as actor operations, such as * receive, react, reply, * etc. * - * @version 0.9.8 + * @version 0.9.10 * @author Philipp Haller */ object Actor { @@ -180,11 +180,11 @@ object Actor { def reply(): Unit = self.reply(()) private[actors] trait Body[a] { - def andThen[b](other: => b): Nothing + def andThen[b](other: => b): Unit } implicit def mkBody[a](body: => a) = new Body[a] { - def andThen[b](other: => b): Nothing = self.seq(body, other) + def andThen[b](other: => b): Unit = self.seq(body, other) } /** @@ -193,7 +193,18 @@ object Actor { * * @param body the code block to be executed */ - def loop(body: => Unit): Nothing = body andThen loop(body) + def loop(body: => Unit): Unit = body andThen loop(body) + + /** + * Causes self to repeatedly execute + * body while the condition + * cond is true. + * + * @param cond the condition to test + * @param body the code block to be executed + */ + def loopWhile(cond: => Boolean)(body: => Unit): Unit = + if (cond) { body andThen loopWhile(cond)(body) } /** * Links self to actor to. @@ -255,10 +266,7 @@ object Actor { /** *

- * This class provides (together with Channel) an - * implementation of event-based actors. - *

- *

+ * This class provides an implementation of event-based actors. * The main ideas of our approach are explained in the two papers *

* * - * @version 0.9.9 + * @version 0.9.10 * @author Philipp Haller */ @serializable @@ -353,44 +361,6 @@ trait Actor extends OutputChannel[Any] { result } -/* - def receiveFrom[T, R](sendr: Sender[T], f: PartialFunction[Any, R]): R = { - assert(Actor.self == this, "receive from channel belonging to other actor") - if (shouldExit) exit() // links - this.synchronized { - tick() - - val tested = new Queue[MessageQueueElement] - var tryMore = true - while (tryMore) { - val qel = mailbox.extractFirst((m: Any) => f.isDefinedAt(m)) - if (null eq qel) { - // either mailbox empty or no match - tryMore = false - waitingFor = f.isDefinedAt - isSuspended = true - suspendActor() - } else { - if (qel.session.isInstanceOf[OutputChannel[T]]) { - received = Some(qel.msg) - sessions = qel.session :: sessions - } else { - // no match - tested += qel - - } - } - } - - waitingFor = waitingForNone - isSuspended = false - } - val result = f(received.get) - sessions = sessions.tail - result - } -*/ - /** * Receives a message from this actor's mailbox within a certain * time span. @@ -539,12 +509,6 @@ trait Actor extends OutputChannel[Any] { } } -/* - def !?[R](msg: Any, res: OutputChannel[R]): R = { - - } -*/ - /** * Sends msg to this actor and awaits reply * (synchronous) within msec milliseconds. @@ -720,19 +684,19 @@ trait Actor extends OutputChannel[Any] { this } - private def seq[a, b](first: => a, next: => b): Nothing = { + private def seq[a, b](first: => a, next: => b): Unit = { val s = Actor.self val killNext = s.kill - s.kill = () => { s.kill = killNext; next; s.kill() } - first + s.kill = () => { + s.kill = killNext - // to avoid stack overflow: instead of directly executing, - // schedule task that executes s.kill() - scheduleActor({ - case 'kill => Actor.self.kill() - }, 'kill) - - throw new SuspendActorException + // to avoid stack overflow: + // instead of directly executing `next`, + // schedule as continuation + scheduleActor({ case _ => next }, 1) + throw new SuspendActorException + } + first } private[actors] var links: List[Actor] = Nil @@ -811,7 +775,6 @@ trait Actor extends OutputChannel[Any] { // links if (!links.isEmpty) exitLinked() - kill() throw new ExitActorException } diff --git a/src/actors/scala/actors/Reaction.scala b/src/actors/scala/actors/Reaction.scala index 2fde1a8a37..9f46e9c0ce 100644 --- a/src/actors/scala/actors/Reaction.scala +++ b/src/actors/scala/actors/Reaction.scala @@ -51,7 +51,7 @@ private[actors] class ExitActorException extends Throwable a.act() else f(msg) - a.exit() + a.kill(); a.exit() } } catch { -- cgit v1.2.3