scala.concurrent.BlockContext

trait BlockContext extends AnyRef

A context to be notified by scala.concurrent.blocking when a thread is about to block. In effect this trait provides the implementation for scala.concurrent.Await . scala.concurrent.Await.result() and scala.concurrent.Await.ready() locates an instance of BlockContext by first looking for one provided through BlockContext.withBlockContext() and failing that, checking whether Thread.currentThread is an instance of BlockContext . So a thread pool can have its java.lang.Thread instances implement BlockContext . There’s a default BlockContext used if the thread doesn’t implement BlockContext .

Typically, you’ll want to chain to the previous BlockContext , like this:

val oldContext = BlockContext.current
val myContext = new BlockContext {
  override def blockOn[T](thunk: =>T)(implicit permission: CanAwait): T = {
    // you'd have code here doing whatever you need to do
    // when the thread is about to block.
    // Then you'd chain to the previous context:
    oldContext.blockOn(thunk)
  }
}
BlockContext.withBlockContext(myContext) {
  // then this block runs with myContext as the handler
  // for scala.concurrent.blocking
}

Abstract Value Members From scala.concurrent.BlockContext

abstract def blockOn[T](thunk: ⇒ T)(implicit permission: CanAwait): T

Used internally by the framework; Designates (and eventually executes) a thunk which potentially blocks the calling java.lang.Thread .

Clients must use scala.concurrent.blocking or scala.concurrent.Await instead. (defined at scala.concurrent.BlockContext)

Full Source:

/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2003-2013, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
\*                                                                      */

package scala.concurrent

/**
 * A context to be notified by `scala.concurrent.blocking` when
 * a thread is about to block. In effect this trait provides
 * the implementation for `scala.concurrent.Await`.
 * `scala.concurrent.Await.result()` and `scala.concurrent.Await.ready()`
 * locates an instance of `BlockContext` by first looking for one
 * provided through `BlockContext.withBlockContext()` and failing that,
 * checking whether `Thread.currentThread` is an instance of `BlockContext`.
 * So a thread pool can have its `java.lang.Thread` instances implement
 * `BlockContext`. There's a default `BlockContext` used if the thread
 * doesn't implement `BlockContext`.
 *
 * Typically, you'll want to chain to the previous `BlockContext`,
 * like this:
 * {{{
 *  val oldContext = BlockContext.current
 *  val myContext = new BlockContext {
 *    override def blockOn[T](thunk: =>T)(implicit permission: CanAwait): T = {
 *      // you'd have code here doing whatever you need to do
 *      // when the thread is about to block.
 *      // Then you'd chain to the previous context:
 *      oldContext.blockOn(thunk)
 *    }
 *  }
 *  BlockContext.withBlockContext(myContext) {
 *    // then this block runs with myContext as the handler
 *    // for scala.concurrent.blocking
 *  }
 *  }}}
 */
trait BlockContext {

  /** Used internally by the framework;
   * Designates (and eventually executes) a thunk which potentially blocks the calling `java.lang.Thread`.
   *
   * Clients must use `scala.concurrent.blocking` or `scala.concurrent.Await` instead.
   */
  def blockOn[T](thunk: =>T)(implicit permission: CanAwait): T
}

object BlockContext {
  private object DefaultBlockContext extends BlockContext {
    override def blockOn[T](thunk: =>T)(implicit permission: CanAwait): T = thunk
  }

  /**
   * @return the `BlockContext` that will be used if no other is found.
   **/
  def defaultBlockContext: BlockContext = DefaultBlockContext

  private val contextLocal = new ThreadLocal[BlockContext]()

  /**
    @return the `BlockContext` that would be used for the current `java.lang.Thread` at this point
   **/
  def current: BlockContext = contextLocal.get match {
    case null => Thread.currentThread match {
      case ctx: BlockContext => ctx
      case _ => DefaultBlockContext
    }
    case some => some
  }

  /**
   * Installs a current `BlockContext` around executing `body`.
   **/
  def withBlockContext[T](blockContext: BlockContext)(body: => T): T = {
    val old = contextLocal.get // can be null
    try {
      contextLocal.set(blockContext)
      body
    } finally {
      contextLocal.set(old)
    }
  }
}