STMImpl

trait STMImpl extends RefFactory with TxnContext with TxnExecutor

STMImpl gathers all of the functionality required to plug an STM implementation into scala.concurrent.stm. See the STMImpl companion object for information on controlling which STMImpl is selected at run time.

STMImpl gathers all of the functionality required to plug an STM implementation into scala.concurrent.stm. See the STMImpl companion object for information on controlling which STMImpl is selected at run time.

Authors

Nathan Bronson

Companion
object
class Object
trait Matchable
class Any
class CCSTM

Value members

Abstract methods

def newCommitBarrier(timeout: Long, unit: TimeUnit): CommitBarrier

Returns a new commit barrier suitable for coordinating commits by this STM implementation.

Returns a new commit barrier suitable for coordinating commits by this STM implementation.

Inherited methods

def apply[Z](block: InTxn => Z)(mt: MaybeTxn): Z

Executes block one or more times until an atomic execution is achieved, buffering and/or locking writes so they are not visible until success.

Executes block one or more times until an atomic execution is achieved, buffering and/or locking writes so they are not visible until success.

Type Params
Z

the return type of the atomic block

Value Params
block

code to execute atomically

Returns

the value returned from block after a successful optimistic concurrency attempt

Inherited from
TxnExecutor
def compareAndSet[A, B](a: Ref[A], a0: A, a1: A, b: Ref[B], b0: B, b1: B): Boolean

Atomically compares and sets two Refs, probably more efficiently then the corresponding transaction. Equivalent to

Atomically compares and sets two Refs, probably more efficiently then the corresponding transaction. Equivalent to

   atomic { implicit t =>
     a() == a0 && b() == b0 && { a() = a1 ; b() = b1 ; true }
   }
Inherited from
TxnExecutor
def compareAndSetIdentity[A <: AnyRef, B <: AnyRef](a: Ref[A], a0: A, a1: A, b: Ref[B], b0: B, b1: B): Boolean

Atomically compares and sets two Refs using identity comparison, probably more efficiently then the corresponding transaction. Equivalent to

Atomically compares and sets two Refs using identity comparison, probably more efficiently then the corresponding transaction. Equivalent to

  atomic { implicit t =>
    val f = (a() eq a0) && (b() eq b0)
    if (f && (a0 ne a1))
      a() = a1
    if (f && (b0 ne b1))
      b() = b1
    f
  }
Inherited from
TxnExecutor

Returns the current InTxn instance if it is active or in the process of committing on the current thread, null otherwise. Always performs a dynamic lookup.

Returns the current InTxn instance if it is active or in the process of committing on the current thread, null otherwise. Always performs a dynamic lookup.

Inherited from
TxnContext
def findCurrent(mt: MaybeTxn): Option[InTxn]

Returns Some(txn) if txn is the InTxn active or in the process of committing on the current thread, None otherwise.

Returns Some(txn) if txn is the InTxn active or in the process of committing on the current thread, None otherwise.

Inherited from
TxnContext
def isControlFlow(x: Throwable): Boolean

Returns true if x should be treated as a transfer of control, rather than an error. Atomic blocks that end with an uncaught control flow exception are committed, while atomic blocks that end with an uncaught error exception are rolled back.

Returns true if x should be treated as a transfer of control, rather than an error. Atomic blocks that end with an uncaught control flow exception are committed, while atomic blocks that end with an uncaught error exception are rolled back.

All implementations of this method must return true for instances that implement scala.util.control.ControlThrowable.

Inherited from
TxnExecutor
def newRef[A](v0: A)(`evidence$1`: ClassTag[A]): Ref[A]

T will not be one of the primitive types (for which a newRef specialization exists).

T will not be one of the primitive types (for which a newRef specialization exists).

Inherited from
RefFactory
def newRef(v0: Unit): Ref[Unit]
Inherited from
RefFactory
def newRef(v0: Double): Ref[Double]
Inherited from
RefFactory
def newRef(v0: Long): Ref[Long]
Inherited from
RefFactory
def newRef(v0: Float): Ref[Float]
Inherited from
RefFactory
def newRef(v0: Int): Ref[Int]
Inherited from
RefFactory
def newRef(v0: Char): Ref[Char]
Inherited from
RefFactory
def newRef(v0: Short): Ref[Short]
Inherited from
RefFactory
def newRef(v0: Byte): Ref[Byte]
Inherited from
RefFactory
def newRef(v0: Boolean): Ref[Boolean]
Inherited from
RefFactory
def newTArray[A](xs: IterableOnce[A])(`evidence$3`: ClassTag[A]): TArray[A]
Inherited from
RefFactory
def newTArray[A](length: Int)(`evidence$2`: ClassTag[A]): TArray[A]
Inherited from
RefFactory
def newTMap[A, B]: TMap[A, B]
Inherited from
RefFactory
def newTMapBuilder[A, B]: Builder[(A, B), TMap[A, B]]
Inherited from
RefFactory
def newTSet[A]: TSet[A]
Inherited from
RefFactory
def newTSetBuilder[A]: Builder[A, TSet[A]]
Inherited from
RefFactory
def newTxnLocal[A](init: => A, initialValue: InTxn => A, beforeCommit: InTxn => Unit, whilePreparing: InTxnEnd => Unit, whileCommitting: InTxnEnd => Unit, afterCommit: A => Unit, afterRollback: Status => Unit, afterCompletion: Status => Unit): TxnLocal[A]
Inherited from
RefFactory
def oneOf[Z](blocks: InTxn => Z*)(mt: MaybeTxn): Z

Atomically executes a transaction that is composed from blocks by joining with a left-biased orAtomic operator. The following two examples are equivalent. Using orAtomic:

Atomically executes a transaction that is composed from blocks by joining with a left-biased orAtomic operator. The following two examples are equivalent. Using orAtomic:

  atomic { implicit t =>
    // body A
  } orAtomic { implicit t =>
    // body B
  } ...

Using oneOf:

  atomic.oneOf( { implicit t: InTxn =>
    // body A
  }, { implicit t: InTxn =>
    // body B
  } )

The first block will be attempted in an optimistic transaction until it either succeeds, fails with no retry possible (in which case the causing exception will be rethrown), or performs a call to retry. If a retry is requested, then the next block will be attempted in the same fashion. If all blocks are explicitly retried then execution resumes at the first block, but only after another context has changed some value read by one of the attempts.

The left-biasing of the orAtomic composition guarantees that if the first block does not call retry, no other blocks will be executed.

Inherited from
TxnExecutor
def postDecisionFailureHandler: (Status, Throwable) => Unit

Returns a function that records, reports or discards exceptions that were thrown from a while-committing, after-commit or after-rollback life-cycle callback.

Returns a function that records, reports or discards exceptions that were thrown from a while-committing, after-commit or after-rollback life-cycle callback.

Inherited from
TxnExecutor
def pushAlternative[Z](mt: MaybeTxn, block: InTxn => Z): Boolean

(rare) Associates an alternative atomic block with the current thread. The next call to apply will consider block to be an alternative. Multiple alternatives may be associated before calling apply. Returns true if this is the first pushed alternative, false otherwise. This method is not usually called directly. Alternative atomic blocks are only attempted if the previous alternatives call retry.

(rare) Associates an alternative atomic block with the current thread. The next call to apply will consider block to be an alternative. Multiple alternatives may be associated before calling apply. Returns true if this is the first pushed alternative, false otherwise. This method is not usually called directly. Alternative atomic blocks are only attempted if the previous alternatives call retry.

Note that it is not required that pushAlternative be called on the same instance of TxnExecutor as apply, just that they have been derived from the same original executor.

Inherited from
TxnExecutor
def retryTimeoutNanos: Option[Long]

Returns Some(t) if t is the retry timeout in nanoseconds used by this TxnExecutor, or None otherwise. If the retry timeout is Some(t) and an atomic block executed by the returned executor blocks with retry or retryFor for more than t nanoseconds the retry will be cancelled with an InterruptedException.

Returns Some(t) if t is the retry timeout in nanoseconds used by this TxnExecutor, or None otherwise. If the retry timeout is Some(t) and an atomic block executed by the returned executor blocks with retry or retryFor for more than t nanoseconds the retry will be cancelled with an InterruptedException.

The retry timeout has essentially the same effect as replacing calls to retry with { retryFor(timeout, NANOS) ; throw new InterruptedException }. Alternately, retryFor(timeout) has roughly the same effect as

  try {
    atomic.withRetryTimeout(timeout) { implicit txn => retry }
  } catch {
    case _: InterruptedException =>
  }
Inherited from
TxnExecutor
def unrecorded[Z](block: InTxn => Z, outerFailure: RollbackCause => Z)(mt: MaybeTxn): Z

Performs a computation in a transaction and returns the result, but always rolls back the transaction. No writes performed by block will be committed or exposed to other threads. This may be useful for heuristic decisions or for debugging, as for the various dbgStr implementations.

Performs a computation in a transaction and returns the result, but always rolls back the transaction. No writes performed by block will be committed or exposed to other threads. This may be useful for heuristic decisions or for debugging, as for the various dbgStr implementations.

'''The caller is responsible for correctness:''' It is a code smell if ''Z'' is a type that is constructed from Ref, TMap, TSet, .....

If this method is executed inside an outer transaction that has status Txn.RolledBack then block can't complete. The default behavior (if outerFailure is null) in that case is to immediately roll back the outer transaction. If a non-null outerFailure handler has been provided, however, it allow this method to return. This is useful when the unrecorded transaction is being used for debugging or logging.

atomic.unrecorded { implicit txn => code } is roughly equivalent to the following, except that the rollback cause used will be Txn.UnrecordedTxnCause:

  case class Tunnel(z: Z) extends Exception {}
  try {
    atomic.withControlFlowRecognizer({
      case Tunnel(_) => false
    }) { implicit txn =>
      throw Tunnel(code)
    }
  } catch {
    case Tunnel(z) => z
  }
Inherited from
TxnExecutor
def withControlFlowRecognizer(pf: PartialFunction[Throwable, Boolean]): TxnExecutor

Returns a TxnExecutor e that is identical to this one, except that e.isControlFlow(x) will return pf(x) if pf.isDefined(x). For exceptions for which pf is not defined the decision will be deferred to the previous implementation.

Returns a TxnExecutor e that is identical to this one, except that e.isControlFlow(x) will return pf(x) if pf.isDefined(x). For exceptions for which pf is not defined the decision will be deferred to the previous implementation.

This function may be combined with TxnExecutor.transformDefault to add system-wide recognition of a control-transfer exception that does not extend scala.util.control.ControlThrowable. For example, to modify the default behavior of all TxnExecutor.isControlFlow calls to accept DSLNonLocalControlTransferException:

  TxnExecutor.transformDefault { e =>
    e.withControlFlowRecognizer {
      case _: DSLNonLocalControlTransferException => true
    }
  }
Inherited from
TxnExecutor
def withPostDecisionFailureHandler(handler: (Status, Throwable) => Unit): TxnExecutor

Returns a TxnExecutor e that is identical to this one, except that e.postDecisionFailureHandler will return handler. This function may be called from inside a function passed to TxnExecutor.transformDefault to change the system-wide post-decision failure handler.

Returns a TxnExecutor e that is identical to this one, except that e.postDecisionFailureHandler will return handler. This function may be called from inside a function passed to TxnExecutor.transformDefault to change the system-wide post-decision failure handler.

Inherited from
TxnExecutor
def withRetryTimeout(timeout: Long, unit: TimeUnit): TxnExecutor

Returns a TxnExecutor that is identical to this one except that it has the specified retry timeout. The default time unit is milliseconds. If the retry timeout expires the retry will be cancelled with an InterruptedException.

Returns a TxnExecutor that is identical to this one except that it has the specified retry timeout. The default time unit is milliseconds. If the retry timeout expires the retry will be cancelled with an InterruptedException.

Inherited from
TxnExecutor
def withRetryTimeoutNanos(timeoutNanos: Option[Long]): TxnExecutor

Returns a TxnExecutor that is identical to this one, except that it has a retryTimeout of timeoutNanos.

Returns a TxnExecutor that is identical to this one, except that it has a retryTimeout of timeoutNanos.

Inherited from
TxnExecutor