summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/actors/scala/actors/Actor.scala27
-rw-r--r--test/files/jvm/actor-sync-send-timeout.scala47
2 files changed, 64 insertions, 10 deletions
diff --git a/src/actors/scala/actors/Actor.scala b/src/actors/scala/actors/Actor.scala
index 25cfbf7865..57e107538c 100644
--- a/src/actors/scala/actors/Actor.scala
+++ b/src/actors/scala/actors/Actor.scala
@@ -590,20 +590,27 @@ trait Actor extends AbstractActor with ReplyReactor with ActorCanReply with Inpu
receiveTimeout
} else {
if (onTimeout.isEmpty) {
- waitingFor = f
- received = None
- isSuspended = true
+ if (!f.isDefinedAt(TIMEOUT))
+ sys.error("unhandled timeout")
+
val thisActor = this
onTimeout = Some(new TimerTask {
- def run() { thisActor.send(TIMEOUT, thisActor) }
+ def run() {
+ thisActor.send(TIMEOUT, thisActor)
+ }
})
Actor.timer.schedule(onTimeout.get, msec)
- scheduler.managedBlock(blocker)
- drainSendBuffer(mailbox)
- // keep going
- () => {}
- } else
- sys.error("unhandled timeout")
+ }
+
+ // It is possible that !onTimeout.isEmpty, but TIMEOUT is not yet in mailbox
+ // See SI-4759
+ waitingFor = f
+ received = None
+ isSuspended = true
+ scheduler.managedBlock(blocker)
+ drainSendBuffer(mailbox)
+ // keep going
+ () => {}
}
}
todo()
diff --git a/test/files/jvm/actor-sync-send-timeout.scala b/test/files/jvm/actor-sync-send-timeout.scala
new file mode 100644
index 0000000000..ed330900b2
--- /dev/null
+++ b/test/files/jvm/actor-sync-send-timeout.scala
@@ -0,0 +1,47 @@
+import scala.actors.Actor
+
+/* This test is a regression test for SI-4759.
+ */
+object Test {
+ val Runs = 5
+
+ def main(args: Array[String]) = {
+ var i = 0
+ while (i < Runs) {
+ i += 1
+ A1 ! 1
+ Thread.sleep(500)
+ }
+ //println("done sending to A1")
+ }
+}
+
+object A2 extends Actor {
+ this.start()
+ def act() {
+ loop {
+ react {
+ case 'stop =>
+ //println("A2 exiting")
+ exit()
+ case _ =>
+ }
+ }
+ }
+}
+
+object A1 extends Actor {
+ this.start()
+ def act() {
+ var i = 0
+ loopWhile(i < Test.Runs) {
+ i += 1
+ react {
+ case any =>
+ A2 !? (500, any)
+ if (i == Test.Runs)
+ A2 ! 'stop
+ }
+ }
+ }
+}