summaryrefslogtreecommitdiff
path: root/src/actors
diff options
context:
space:
mode:
Diffstat (limited to 'src/actors')
-rw-r--r--src/actors/scala/actors/Actor.scala8
-rw-r--r--src/actors/scala/actors/Debug.scala9
-rw-r--r--src/actors/scala/actors/Reactor.scala22
-rw-r--r--src/actors/scala/actors/ReactorTask.scala1
-rw-r--r--src/actors/scala/actors/ReplyReactor.scala8
5 files changed, 44 insertions, 4 deletions
diff --git a/src/actors/scala/actors/Actor.scala b/src/actors/scala/actors/Actor.scala
index fb90cb9c46..907389b9f0 100644
--- a/src/actors/scala/actors/Actor.scala
+++ b/src/actors/scala/actors/Actor.scala
@@ -646,6 +646,7 @@ trait Actor extends AbstractActor with ReplyReactor with ReplyableActor {
}
// guarded by lock of this
+ // never throws SuspendActorException
private[actors] override def scheduleActor(f: Any =>? Unit, msg: Any) =
if ((f eq null) && (continuation eq null)) {
// do nothing (timeout is handled instead)
@@ -825,6 +826,13 @@ trait Actor extends AbstractActor with ReplyReactor with ReplyableActor {
resumeActor()
else if (waitingFor ne waitingForNone) {
scheduleActor(continuation, null)
+ /* Here we should not throw a SuspendActorException,
+ since the current method is called from an actor that
+ is in the process of exiting.
+
+ Therefore, the contract for scheduleActor is that
+ it never throws a SuspendActorException.
+ */
}
}
}
diff --git a/src/actors/scala/actors/Debug.scala b/src/actors/scala/actors/Debug.scala
index 481b68d7f4..bad19b8aeb 100644
--- a/src/actors/scala/actors/Debug.scala
+++ b/src/actors/scala/actors/Debug.scala
@@ -27,6 +27,15 @@ object Debug {
def error(s: String) =
if (lev > 0) System.err.println("Error: " + s)
+
+ def doInfo(b: => Unit) =
+ if (lev > 2) b
+
+ def doWarning(b: => Unit) =
+ if (lev > 1) b
+
+ def doError(b: => Unit) =
+ if (lev > 0) b
}
class Debug(tag: String) {
diff --git a/src/actors/scala/actors/Reactor.scala b/src/actors/scala/actors/Reactor.scala
index d641f54eb6..8545b92d1e 100644
--- a/src/actors/scala/actors/Reactor.scala
+++ b/src/actors/scala/actors/Reactor.scala
@@ -108,8 +108,17 @@ trait Reactor extends OutputChannel[Any] {
// assert continuation != null
if (onSameThread)
continuation(item._1)
- else
+ else {
scheduleActor(continuation, item._1)
+ /* Here, we throw a SuspendActorException to avoid
+ terminating this actor when the current ReactorTask
+ is finished.
+
+ The SuspendActorException skips the termination code
+ in ReactorTask.
+ */
+ throw Actor.suspendException
+ }
}
def !(msg: Any) {
@@ -149,7 +158,14 @@ trait Reactor extends OutputChannel[Any] {
// keep going
} else {
waitingFor = handlesMessage
- done = true
+ /* Here, we throw a SuspendActorException to avoid
+ terminating this actor when the current ReactorTask
+ is finished.
+
+ The SuspendActorException skips the termination code
+ in ReactorTask.
+ */
+ throw Actor.suspendException
}
}
} else {
@@ -171,6 +187,8 @@ trait Reactor extends OutputChannel[Any] {
* an actors act method.
*
* assume handler != null
+ *
+ * never throws SuspendActorException
*/
private[actors] def scheduleActor(handler: Any =>? Unit, msg: Any) = {
val fun = () => handler(msg)
diff --git a/src/actors/scala/actors/ReactorTask.scala b/src/actors/scala/actors/ReactorTask.scala
index 28e93bbbff..f6ec67e94c 100644
--- a/src/actors/scala/actors/ReactorTask.scala
+++ b/src/actors/scala/actors/ReactorTask.scala
@@ -46,6 +46,7 @@ private[actors] class ReactorTask[T >: Null <: Reactor](var reactor: T, var fun:
case e: Exception =>
Debug.info(reactor+": caught "+e)
+ Debug.doInfo { e.printStackTrace() }
reactor.terminated()
afterExecuting(e)
} finally {
diff --git a/src/actors/scala/actors/ReplyReactor.scala b/src/actors/scala/actors/ReplyReactor.scala
index 4b31369db4..64860f4d38 100644
--- a/src/actors/scala/actors/ReplyReactor.scala
+++ b/src/actors/scala/actors/ReplyReactor.scala
@@ -57,8 +57,11 @@ trait ReplyReactor extends Reactor with ReplyableReactor {
// assert continuation != null
if (onSameThread)
continuation(item._1)
- else
+ else {
scheduleActor(continuation, item._1)
+ // see Reactor.resumeReceiver
+ throw Actor.suspendException
+ }
}
// assume continuation != null
@@ -83,7 +86,8 @@ trait ReplyReactor extends Reactor with ReplyableReactor {
// keep going
} else {
waitingFor = handlesMessage
- done = true
+ // see Reactor.searchMailbox
+ throw Actor.suspendException
}
}
} else {