Skip to content

Instantly share code, notes, and snippets.

@ajaychandran
Last active December 28, 2015 13:36
Show Gist options
  • Save ajaychandran/c2229a351e5bb68e208f to your computer and use it in GitHub Desktop.
Save ajaychandran/c2229a351e5bb68e208f to your computer and use it in GitHub Desktop.
final class FinalizerCancelable(finalizer: () => Unit) extends BooleanCancelable {
private val state = new AtomicReference(FinalizerCancelable.State())
def isCanceled: Boolean = state.get().canceled
def acquire(): BooleanCancelable = {
state.get() match {
case FinalizerCancelable.State(true, _) => BooleanCancelable.alreadyCanceled
case s => state.compareAndSet(s, s.copy(active = s.active + 1)) match {
case false => acquire()
case true => BooleanCancelable(release())
}
}
}
def cancel(): Boolean = state.get match {
case FinalizerCancelable.State(true, _) => false
case s => state.compareAndSet(s, s.copy(canceled = true)) match {
case true =>
finalizer()
true
case false => cancel()
}
}
private def release() = state.get match {
case FinalizerCancelable.State(true, _) =>
case s => state.compareAndSet(s, s.copy(active = s.active - 1)) match {
case true => state.get match {
case s@FinalizerCancelable.State(false, 0) => state.compareAndSet(s, s.copy(canceled = true)) match {
case true => finalizer()
case _ =>
}
case _ =>
}
case _ =>
}
}
}
object FinalizerCancelable {
def apply(cb: => Unit): FinalizerCancelable = new FinalizerCancelable(() => cb)
case class State(canceled: Boolean = false, active: Int = 0)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment