diff options
author | Philipp Haller <hallerp@gmail.com> | 2010-04-22 08:04:12 +0000 |
---|---|---|
committer | Philipp Haller <hallerp@gmail.com> | 2010-04-22 08:04:12 +0000 |
commit | dcbffd4dc50c7e2540fd4770492b86108d3254fc (patch) | |
tree | ced3f0c9081b93fd07ff28bd2fcd7f5d0a436fb3 /src | |
parent | 3861a3a42e4347c733a3c15a7cd85fa86d1d1011 (diff) | |
download | scala-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')
-rw-r--r-- | src/actors/scala/actors/ActorTask.scala | 12 | ||||
-rw-r--r-- | src/actors/scala/actors/Reactor.scala | 6 | ||||
-rw-r--r-- | src/actors/scala/actors/ReactorTask.scala | 35 | ||||
-rw-r--r-- | src/actors/scala/actors/UncaughtException.scala | 2 |
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() = |