All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scala.concurrent.stm.PendingAtomicBlock.scala Maven / Gradle / Ivy

The newest version!
/* scala-stm - (c) 2009-2011, Stanford University, PPL */

package scala.concurrent.stm

/** Instances of `PendingAtomicBlock` defer the execution of an atomic block
 *  until all of the alternatives can be gathered from the user.  There is an
 *  implicit conversion in the `stm` package object from any type `A` to a
 *  `PendingAtomicBlock[A]`, which will kick in if there is an attempt to call
 *  `.orAtomic` on a value.
 *
 *  @author Nathan Bronson
 */
class PendingAtomicBlock[A](above: => A) {

  /** See `atomic.oneOf`. */
  def orAtomic[B >: A](below: InTxn => B)(implicit mt: MaybeTxn): B = {
    // Execution of Delayed.orAtomic proceeds bottom to top, with the upper
    // portions being captured by-name in `above`.  The actual transactional
    // execution is all performed inside the top-most block (the one that
    // used atomic rather than orAtomic).  If a block other than the top one
    // is the one that eventually succeeds, we must tunnel the value out with
    // an exception because the alternatives may have a wider type.  We only
    // catch the exception if we are the bottom-most alternative, because
    // only it is guaranteed to have been fully widened.
    if (!atomic.pushAlternative(mt, below)) {
      // we're not the bottom
      above
    } else {
      // we're the bottom, this is the end of the result tunnel
      try {
        above
      } catch {
        case impl.AlternativeResult(x) => x.asInstanceOf[B]
      }
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy