Simplifying the code inside Children and RepointableActorRef

This commit is contained in:
Viktor Klang 2012-11-14 14:34:31 +01:00
parent cbd301247a
commit 5478fe094c
2 changed files with 35 additions and 32 deletions

View file

@ -52,12 +52,15 @@ private[akka] class RepointableActorRef(
*
* This is protected so that others can have different initialization.
*/
def initialize(): this.type = {
val uid = ThreadLocalRandom.current.nextInt()
swapCell(new UnstartedCell(system, this, props, supervisor, uid))
supervisor.sendSystemMessage(Supervise(this, uid))
this
}
def initialize(): this.type =
underlying match {
case null
val uid = ThreadLocalRandom.current.nextInt()
swapCell(new UnstartedCell(system, this, props, supervisor, uid))
supervisor.sendSystemMessage(Supervise(this, uid))
this
case other this
}
/**
* This method is supposed to be called by the supervisor in handleSupervise()
@ -65,13 +68,12 @@ private[akka] class RepointableActorRef(
* modification of the `underlying` field, though it is safe to send messages
* at any time.
*/
def activate(): this.type = {
def activate(): this.type =
underlying match {
case u: UnstartedCell u.replaceWith(newCell(u))
case _ // this happens routinely for things which were created async=false
case u: UnstartedCell u.replaceWith(newCell(u)); this
case null throw new IllegalStateException("underlying cell is null")
case _ this // this happens routinely for things which were created async=false
}
this
}
/**
* This is called by activate() to obtain the cell which is to replace the

View file

@ -52,19 +52,24 @@ private[akka] trait Children { this: ActorCell ⇒
}
final def stop(actor: ActorRef): Unit = {
val started = actor match {
case r: RepointableRef r.isStarted
case _ true
if (childrenRefs.getByRef(actor).isDefined) {
@tailrec def shallDie(ref: ActorRef): Boolean = {
val c = childrenRefs
swapChildrenRefs(c, c.shallDie(ref)) || shallDie(ref)
}
if (actor match {
case r: RepointableRef r.isStarted
case _ true
}) shallDie(actor)
}
if (childrenRefs.getByRef(actor).isDefined && started) shallDie(actor)
actor.asInstanceOf[InternalActorRef].stop()
}
/*
* low level CAS helpers
*/
@inline private def swapChildrenRefs(oldChildren: ChildrenContainer, newChildren: ChildrenContainer): Boolean =
@inline private final def swapChildrenRefs(oldChildren: ChildrenContainer, newChildren: ChildrenContainer): Boolean =
Unsafe.instance.compareAndSwapObject(this, AbstractActorCell.childrenOffset, oldChildren, newChildren)
@tailrec final def reserveChild(name: String): Boolean = {
@ -89,18 +94,6 @@ private[akka] trait Children { this: ActorCell ⇒
}
}
@tailrec final protected def shallDie(ref: ActorRef): Boolean = {
val c = childrenRefs
swapChildrenRefs(c, c.shallDie(ref)) || shallDie(ref)
}
@tailrec final private def removeChild(ref: ActorRef): ChildrenContainer = {
val c = childrenRefs
val n = c.remove(ref)
if (swapChildrenRefs(c, n)) n
else removeChild(ref)
}
@tailrec final protected def setChildrenTerminationReason(reason: ChildrenContainer.SuspendReason): Boolean = {
childrenRefs match {
case c: ChildrenContainer.TerminatingChildrenContainer
@ -143,10 +136,18 @@ private[akka] trait Children { this: ActorCell ⇒
protected def getAllChildStats: immutable.Iterable[ChildRestartStats] = childrenRefs.stats
protected def removeChildAndGetStateChange(child: ActorRef): Option[SuspendReason] = {
childrenRefs match {
@tailrec def removeChild(ref: ActorRef): ChildrenContainer = {
val c = childrenRefs
val n = c.remove(ref)
if (swapChildrenRefs(c, n)) n else removeChild(ref)
}
childrenRefs match { // The match must be performed BEFORE the removeChild
case TerminatingChildrenContainer(_, _, reason)
val newContainer = removeChild(child)
if (!newContainer.isInstanceOf[TerminatingChildrenContainer]) Some(reason) else None
removeChild(child) match {
case c: TerminatingChildrenContainer None
case _ Some(reason)
}
case _
removeChild(child)
None