summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Haller <hallerp@gmail.com>2010-05-25 14:58:42 +0000
committerPhilipp Haller <hallerp@gmail.com>2010-05-25 14:58:42 +0000
commit4b10a4ca64f3d96a33a7f7badbf2a74e1c176fc4 (patch)
tree52b5047b7cfb01993c5ab674ab0520ef9da6ce3c
parent5628970b43eefcd892320941ea6f937a7ce09b6a (diff)
downloadscala-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.scala30
-rw-r--r--src/actors/scala/actors/Reactor.scala31
-rw-r--r--test/files/jvm/t3470.check3
-rw-r--r--test/files/jvm/t3470.scala30
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()
+ }
+
+}