in src/main/scala/com/twitter/stitch/Stitch.scala [2300:2336]
override def runner(): Runner[Unit, Unit] = this
override def run(): Future[Unit] = p
override def add(call: Unit): Stitch[Unit] = Stitch.future(p)
override def simplify(pending: Pending): Stitch[T] = {
// short circuit if we're already done
if (currentSync.isInstanceOf[Const[T]]) {
currentSync
} else {
// synchronize using an atomic counter since it should only be done by a single pending instance at a time
// any thread can add to the counter but only the first one can decrement it, this avoids locks.
if (nwaiters.getAndIncrement() == 0) {
// short circuit if we're already done
if (currentSync.isInstanceOf[Const[T]]) {
nwaiters.set(0)
return currentSync
} else {
do {
currentSync = currentSync.simplify(pending)
currentSync match {
case _: Const[_] => // current is done, so clean everything up and return
p.setDone() // complete `p` so concurrent callers will `simplify` again
nwaiters.set(0) // reset `nwaiters` to 0 since theres no more work to be done
return currentSync // return the `currentSync`
case _ => // current isn't done
}
} while (nwaiters.decrementAndGet() > 0)
// simplified as much as possible but still not done
}
}
// if we just simplified down to a `Const` we would have returned in the loop above
// so instead we add a callback which calls `simplify` when `p` is completed
pending.add((), this)
// return `this` since it needs to be simplified again later
this
}
}