diff options
author | Philipp Haller <hallerp@gmail.com> | 2010-05-25 14:58:42 +0000 |
---|---|---|
committer | Philipp Haller <hallerp@gmail.com> | 2010-05-25 14:58:42 +0000 |
commit | 4b10a4ca64f3d96a33a7f7badbf2a74e1c176fc4 (patch) | |
tree | 52b5047b7cfb01993c5ab674ab0520ef9da6ce3c | |
parent | 5628970b43eefcd892320941ea6f937a7ce09b6a (diff) | |
download | scala-4b10a4ca64f3d96a33a7f7badbf2a74e1c176fc4.tar.gz scala-4b10a4ca64f3d96a33a7f7badbf2a74e1c176fc4.tar.bz2 scala-4b10a4ca64f3d96a33a7f7badbf2a74e1c176fc4.zip |
Addresses see #3470 by adding a method Reactor....
Addresses see #3470 by adding a method Reactor.restart. Review by rompf.
-rw-r--r-- | src/actors/scala/actors/Actor.scala | 30 | ||||
-rw-r--r-- | src/actors/scala/actors/Reactor.scala | 31 | ||||
-rw-r--r-- | test/files/jvm/t3470.check | 3 | ||||
-rw-r--r-- | test/files/jvm/t3470.scala | 30 |
4 files changed, 70 insertions, 24 deletions
diff --git a/src/actors/scala/actors/Actor.scala b/src/actors/scala/actors/Actor.scala index 988e7dda6c..8caa624f67 100644 --- a/src/actors/scala/actors/Actor.scala +++ b/src/actors/scala/actors/Actor.scala @@ -622,24 +622,22 @@ trait Actor extends AbstractActor with ReplyReactor with ActorCanReply with Inpu _state == Actor.State.Terminated } - override def start(): Actor = synchronized { - if (_state == Actor.State.New) { - _state = Actor.State.Runnable - - // Reset various flags. - // - // Note that we do *not* reset `trapExit`. The reason is that - // users should be able to set the field in the constructor - // and before `act` is called. - exitReason = 'normal - shouldExit = false + // guarded by this + private[actors] override def dostart() { + // Reset various flags. + // + // Note that we do *not* reset `trapExit`. The reason is that + // users should be able to set the field in the constructor + // and before `act` is called. + exitReason = 'normal + shouldExit = false - scheduler newActor this - scheduler execute (new Reaction(this)) + super.dostart() + } - this - } else - this + override def start(): Actor = synchronized { + super.start() + this } override def getState: Actor.State.Value = synchronized { diff --git a/src/actors/scala/actors/Reactor.scala b/src/actors/scala/actors/Reactor.scala index b5b9080c27..1c1dfdbd7a 100644 --- a/src/actors/scala/actors/Reactor.scala +++ b/src/actors/scala/actors/Reactor.scala @@ -215,17 +215,32 @@ trait Reactor[Msg >: Null] extends OutputChannel[Msg] with Combinators { scheduler executeFromActor makeReaction(null, handler, msg) } + // guarded by this + private[actors] def dostart() { + _state = Actor.State.Runnable + scheduler newActor this + scheduler execute makeReaction(() => act(), null, null) + } + /** - * Starts this $actor. + * Starts this $actor. This method is idempotent. */ def start(): Reactor[Msg] = synchronized { - if (_state == Actor.State.New) { - _state = Actor.State.Runnable - scheduler newActor this - scheduler execute makeReaction(() => act()) - this - } else - this + if (_state == Actor.State.New) + dostart() + this + } + + /** + * Restarts this $actor. + * + * @throws java.lang.IllegalStateException if the $actor is not in state `Actor.State.Terminated` + */ + def restart(): Unit = synchronized { + if (_state == Actor.State.Terminated) + dostart() + else + throw new IllegalStateException("restart only in state "+Actor.State.Terminated) } /** Returns the execution state of this $actor. diff --git a/test/files/jvm/t3470.check b/test/files/jvm/t3470.check new file mode 100644 index 0000000000..94cb526756 --- /dev/null +++ b/test/files/jvm/t3470.check @@ -0,0 +1,3 @@ +A: started: 1 +A: started: 2 +A: started: 3 diff --git a/test/files/jvm/t3470.scala b/test/files/jvm/t3470.scala new file mode 100644 index 0000000000..5e4242cdd7 --- /dev/null +++ b/test/files/jvm/t3470.scala @@ -0,0 +1,30 @@ +import scala.actors._ + +object Test { + + def expectActorState(a: Reactor[T] forSome { type T }, s: Actor.State.Value) { + var done = false + var i = 0 + while (!done) { + i = i + 1 + if (i == 10) { // only wait for 2 seconds total + println("FAIL ["+a+": expected "+s+"]") + done = true + } + + Thread.sleep(200) + if (a.getState == s) // success + done = true + } + } + + def main(args: Array[String]) { + val a = new Actor { var c = 0; def act() = { c += 1; println("A: started: " + c) } } + a.start() + expectActorState(a, Actor.State.Terminated) + a.restart() + expectActorState(a, Actor.State.Terminated) + a.restart() + } + +} |