diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorSystemSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorSystemSpec.scala index 5f295de702..486761279a 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorSystemSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorSystemSpec.scala @@ -270,6 +270,7 @@ class ActorSystemSpec extends AkkaSpec(ActorSystemSpec.config) with ImplicitSend val t = probe.expectMsg(Terminated(a)(existenceConfirmed = true, addressTerminated = false)) t.existenceConfirmed must be(true) t.addressTerminated must be(false) + system.shutdown() } "shut down when /user escalates" in { diff --git a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala index 184478c727..a593c6dde8 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala @@ -550,6 +550,7 @@ class LocalActorRefProvider( def init(_system: ActorSystemImpl) { system = _system + rootGuardian.start() // chain death watchers so that killing guardian stops the application systemGuardian.sendSystemMessage(Watch(guardian, systemGuardian)) rootGuardian.sendSystemMessage(Watch(systemGuardian, rootGuardian)) diff --git a/akka-actor/src/main/scala/akka/dispatch/AbstractDispatcher.scala b/akka-actor/src/main/scala/akka/dispatch/AbstractDispatcher.scala index 57f905ece8..352338f64a 100644 --- a/akka-actor/src/main/scala/akka/dispatch/AbstractDispatcher.scala +++ b/akka-actor/src/main/scala/akka/dispatch/AbstractDispatcher.scala @@ -184,6 +184,13 @@ abstract class MessageDispatcher(val prerequisites: DispatcherPrerequisites) ext @tailrec private final def addInhabitants(add: Long): Long = { val c = inhabitants val r = c + add + if (r < 0) { + // We haven't succeeded in decreasing the inhabitants yet but the simple fact that we're trying to + // go below zero means that there is an imbalance and we might as well throw the exception + val e = new IllegalStateException("ACTOR SYSTEM CORRUPTED!!! A dispatcher can't have less than 0 inhabitants!") + reportFailure(e) + throw e + } if (Unsafe.instance.compareAndSwapLong(this, inhabitantsOffset, c, r)) r else addInhabitants(add) } @@ -236,18 +243,16 @@ abstract class MessageDispatcher(val prerequisites: DispatcherPrerequisites) ext } @tailrec - private final def ifSensibleToDoSoThenScheduleShutdown(): Unit = inhabitants match { - case 0 ⇒ - shutdownSchedule match { - case UNSCHEDULED ⇒ - if (updateShutdownSchedule(UNSCHEDULED, SCHEDULED)) scheduleShutdownAction() - else ifSensibleToDoSoThenScheduleShutdown() - case SCHEDULED ⇒ - if (updateShutdownSchedule(SCHEDULED, RESCHEDULED)) () - else ifSensibleToDoSoThenScheduleShutdown() - case RESCHEDULED ⇒ - } - case _ ⇒ + private final def ifSensibleToDoSoThenScheduleShutdown(): Unit = { + if (inhabitants <= 0) shutdownSchedule match { + case UNSCHEDULED ⇒ + if (updateShutdownSchedule(UNSCHEDULED, SCHEDULED)) scheduleShutdownAction() + else ifSensibleToDoSoThenScheduleShutdown() + case SCHEDULED ⇒ + if (updateShutdownSchedule(SCHEDULED, RESCHEDULED)) () + else ifSensibleToDoSoThenScheduleShutdown() + case RESCHEDULED ⇒ + } } private def scheduleShutdownAction(): Unit = { diff --git a/akka-remote/src/main/scala/akka/remote/RemoteDaemon.scala b/akka-remote/src/main/scala/akka/remote/RemoteDaemon.scala index d1add9522a..850518b245 100644 --- a/akka-remote/src/main/scala/akka/remote/RemoteDaemon.scala +++ b/akka-remote/src/main/scala/akka/remote/RemoteDaemon.scala @@ -79,6 +79,7 @@ private[akka] class RemoteSystemDaemon( path, systemService = false, Some(deploy), lookupDeploy = true, async = false) addChild(subpath.mkString("/"), actor) actor.sendSystemMessage(Watch(actor, this)) + actor.start() } if (isTerminating) log.error("Skipping [{}] to RemoteSystemDaemon on [{}] while terminating", message, path.address) case _ ⇒