summaryrefslogtreecommitdiff
path: root/src/actors
diff options
context:
space:
mode:
authorPhilipp Haller <hallerp@gmail.com>2010-04-22 08:04:12 +0000
committerPhilipp Haller <hallerp@gmail.com>2010-04-22 08:04:12 +0000
commitdcbffd4dc50c7e2540fd4770492b86108d3254fc (patch)
treeced3f0c9081b93fd07ff28bd2fcd7f5d0a436fb3 /src/actors
parent3861a3a42e4347c733a3c15a7cd85fa86d1d1011 (diff)
downloadscala-dcbffd4dc50c7e2540fd4770492b86108d3254fc.tar.gz
scala-dcbffd4dc50c7e2540fd4770492b86108d3254fc.tar.bz2
scala-dcbffd4dc50c7e2540fd4770492b86108d3254fc.zip
Reactor.exceptionHandler is defined on Throwabl...
Reactor.exceptionHandler is defined on Throwable instead of Exception. Fixes potential problem with visibility of changes to a field. Review by plocinic.
Diffstat (limited to 'src/actors')
-rw-r--r--src/actors/scala/actors/ActorTask.scala12
-rw-r--r--src/actors/scala/actors/Reactor.scala6
-rw-r--r--src/actors/scala/actors/ReactorTask.scala35
-rw-r--r--src/actors/scala/actors/UncaughtException.scala2
4 files changed, 30 insertions, 25 deletions
diff --git a/src/actors/scala/actors/ActorTask.scala b/src/actors/scala/actors/ActorTask.scala
index 2fa24f93af..ea8624e426 100644
--- a/src/actors/scala/actors/ActorTask.scala
+++ b/src/actors/scala/actors/ActorTask.scala
@@ -25,11 +25,13 @@ private[actors] class ActorTask(actor: Actor,
protected override def beginExecution() {
super.beginExecution()
- if (actor.shouldExit)
- actor.exit()
+ actor.synchronized { // shouldExit guarded by actor
+ if (actor.shouldExit)
+ actor.exit()
+ }
}
- protected override def terminateExecution(e: Exception) {
+ protected override def terminateExecution(e: Throwable) {
val senderInfo = try { Some(actor.sender) } catch {
case _: Exception => None
}
@@ -41,7 +43,9 @@ private[actors] class ActorTask(actor: Actor,
actor.synchronized {
if (!actor.links.isEmpty)
- actor exitLinked uncaught
+ actor.exitLinked(uncaught)
+ else
+ super.terminateExecution(e)
}
}
diff --git a/src/actors/scala/actors/Reactor.scala b/src/actors/scala/actors/Reactor.scala
index 85dcd57189..41f959d8f9 100644
--- a/src/actors/scala/actors/Reactor.scala
+++ b/src/actors/scala/actors/Reactor.scala
@@ -84,7 +84,11 @@ trait Reactor[Msg >: Null] extends OutputChannel[Msg] with Combinators {
*/
def act(): Unit
- protected[actors] def exceptionHandler: PartialFunction[Exception, Unit] =
+ /**
+ * This partial function is applied to `Throwable`s that propagate out of
+ * this $actor's body.
+ */
+ protected[actors] def exceptionHandler: PartialFunction[Throwable, Unit] =
Map()
protected[actors] def scheduler: IScheduler =
diff --git a/src/actors/scala/actors/ReactorTask.scala b/src/actors/scala/actors/ReactorTask.scala
index 3f9ebb6fa7..b4e09ef7f8 100644
--- a/src/actors/scala/actors/ReactorTask.scala
+++ b/src/actors/scala/actors/ReactorTask.scala
@@ -31,17 +31,17 @@ private[actors] class ReactorTask[Msg >: Null](var reactor: Reactor[Msg],
try {
beginExecution()
try {
- try {
- if (fun eq null)
- handler(msg)
- else
- fun()
- } catch {
- case e: Exception if (reactor.exceptionHandler.isDefinedAt(e)) =>
- reactor.exceptionHandler(e)
- }
+ if (fun eq null)
+ handler(msg)
+ else
+ fun()
} catch {
case _: KillActorControl =>
+ // do nothing
+
+ case e: Throwable if !e.isInstanceOf[SuspendActorControl] &&
+ reactor.exceptionHandler.isDefinedAt(e) =>
+ reactor.exceptionHandler(e)
}
reactor.kill()
}
@@ -49,17 +49,11 @@ private[actors] class ReactorTask[Msg >: Null](var reactor: Reactor[Msg],
case _: SuspendActorControl =>
// do nothing (continuation is already saved)
- case e: Exception =>
- // print message on default error stream
- val msgException = "Uncaught exception in "+reactor+"\n"
- val msgMessage = if (msg != null) "Message: "+msg+"\n" else ""
- Debug.doWarning {
- Console.err.print(msgException + msgMessage)
- e.printStackTrace()
- }
-
+ case e: Throwable =>
terminateExecution(e)
reactor.terminated()
+ if (!e.isInstanceOf[Exception])
+ throw e
} finally {
suspendExecution()
this.reactor = null
@@ -77,6 +71,9 @@ private[actors] class ReactorTask[Msg >: Null](var reactor: Reactor[Msg],
protected def suspendExecution() {}
- protected def terminateExecution(e: Exception) {}
+ protected def terminateExecution(e: Throwable) {
+ Console.err.println(reactor+": caught "+e)
+ e.printStackTrace()
+ }
}
diff --git a/src/actors/scala/actors/UncaughtException.scala b/src/actors/scala/actors/UncaughtException.scala
index 54c28f66cf..1829d48606 100644
--- a/src/actors/scala/actors/UncaughtException.scala
+++ b/src/actors/scala/actors/UncaughtException.scala
@@ -23,7 +23,7 @@ class UncaughtException[Msg >: Null](val actor: Reactor[Msg],
val message: Option[Msg],
val sender: Option[OutputChannel[Any]],
val thread: Thread,
- cause: Exception)
+ cause: Throwable)
extends Exception(cause) {
override def toString() =