summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/actors/scala/actors/Actor.scala20
-rw-r--r--test/files/jvm/actor-sync-send-timeout.scala47
-rw-r--r--test/files/jvm/t3838.check1
-rw-r--r--test/files/jvm/t3838.scala15
4 files changed, 78 insertions, 5 deletions
diff --git a/src/actors/scala/actors/Actor.scala b/src/actors/scala/actors/Actor.scala
index f49dd2e247..a5361e44ed 100644
--- a/src/actors/scala/actors/Actor.scala
+++ b/src/actors/scala/actors/Actor.scala
@@ -565,14 +565,24 @@ trait Actor extends AbstractActor with ReplyReactor with ActorCanReply with Inpu
done = true
receiveTimeout
} else {
+ if (onTimeout.isEmpty) {
+ if (!f.isDefinedAt(TIMEOUT))
+ sys.error("unhandled timeout")
+
+ val thisActor = this
+ onTimeout = Some(new TimerTask {
+ def run() {
+ thisActor.send(TIMEOUT, thisActor)
+ }
+ })
+ Actor.timer.schedule(onTimeout.get, msec)
+ }
+
+ // It is possible that !onTimeout.isEmpty, but TIMEOUT is not yet in mailbox
+ // See SI-4759
waitingFor = f
received = None
isSuspended = true
- val thisActor = this
- onTimeout = Some(new TimerTask {
- def run() { thisActor.send(TIMEOUT, thisActor) }
- })
- Actor.timer.schedule(onTimeout.get, msec)
scheduler.managedBlock(blocker)
drainSendBuffer(mailbox)
// keep going
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
+ }
+ }
+ }
+}
diff --git a/test/files/jvm/t3838.check b/test/files/jvm/t3838.check
new file mode 100644
index 0000000000..154227a350
--- /dev/null
+++ b/test/files/jvm/t3838.check
@@ -0,0 +1 @@
+caught java.lang.RuntimeException: unhandled timeout
diff --git a/test/files/jvm/t3838.scala b/test/files/jvm/t3838.scala
new file mode 100644
index 0000000000..ba8f15fc31
--- /dev/null
+++ b/test/files/jvm/t3838.scala
@@ -0,0 +1,15 @@
+import scala.actors.Actor._
+
+object Test {
+ def main(args: Array[String]) {
+ actor {
+ try {
+ receiveWithin(1) {
+ case str: String => println(str)
+ }
+ } catch {
+ case e: Exception => println("caught "+e)
+ }
+ }
+ }
+}