Simplifying the code inside Children and RepointableActorRef
This commit is contained in:
parent
cbd301247a
commit
5478fe094c
2 changed files with 35 additions and 32 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue