open class Sequenced> { protected inner class Internals : Element, Key, Continuation, suspend (suspend Self.() -> (Unit)) -> (Unit) { override val key get() = this override val context get() = this private val left get() = continuation!!.context override fun get(key: Key) = if (key === this) this as E else left[key] override fun fold(initial: R, operation: (R, Element) -> R) = operation(left.fold(initial, operation), this) override fun minusKey(key: Key<*>) = if (key === this) left else this + left.minusKey(key) override fun resumeWith(result: Result) = continuation!!.let { continuation = null; it.resumeWith(result) } override fun toString() = this@Sequenced.toString() override suspend fun invoke(block: suspend Self.() -> (Unit)) { block(this@Sequenced as Self) while (changes.decrementAndGet() > 0) { var grabbed: Node? do { grabbed = tail.get() } while (grabbed == null || !tail.compareAndSet(grabbed, null)) while (true) { var node = grabbed var prior = grabbed while (node!!.previous != null) { prior = node node = node.previous } node.block(this@Sequenced) node.continuation.resume(Unit) if (prior == grabbed) break changes.decrementAndGet() prior!!.previous = null } } } } protected inner class Node( val block: suspend Self.() -> (Unit), val continuation: Continuation, var previous: Node? = null ) @Volatile protected var continuation: Continuation? = null protected val internals = Internals() protected val changes = AtomicInteger(0) protected val tail = AtomicReference(null) protected open suspend fun proceed() {} protected open suspend fun update(block: suspend Self.() -> (Unit)) { if (currentCoroutineContext()[internals] != null) { proceed(); block(this@Sequenced as Self) } else suspendCoroutine { if (changes.getAndIncrement() == 0) { continuation = it internals.startCoroutine(block, internals) } else { val node = Node(block, it); do { node.previous = tail.get() } while (!tail.compareAndSet(node.previous, node)) } } } override fun toString() = "${hashCode()}" }