//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.util.thread;

import java.util.concurrent.Callable;

A task (typically either a Runnable or Callable that declares how it will behave when invoked:

  • blocking, the invocation will certainly block (e.g. performs blocking I/O)
  • non-blocking, the invocation will certainly not block
  • either, the invocation may block

Static methods and are provided that allow the current thread to be tagged with a ThreadLocal to indicate if it has a blocking invocation type.

/** * <p>A task (typically either a {@link Runnable} or {@link Callable} * that declares how it will behave when invoked:</p> * <ul> * <li>blocking, the invocation will certainly block (e.g. performs blocking I/O)</li> * <li>non-blocking, the invocation will certainly <strong>not</strong> block</li> * <li>either, the invocation <em>may</em> block</li> * </ul> * * <p> * Static methods and are provided that allow the current thread to be tagged * with a {@link ThreadLocal} to indicate if it has a blocking invocation type. * </p> */
public interface Invocable { enum InvocationType { BLOCKING, NON_BLOCKING, EITHER } static ThreadLocal<Boolean> __nonBlocking = new ThreadLocal<>();
Test if the current thread has been tagged as non blocking
Returns:True if the task the current thread is running has indicated that it will not block.
/** * Test if the current thread has been tagged as non blocking * * @return True if the task the current thread is running has * indicated that it will not block. */
public static boolean isNonBlockingInvocation() { return Boolean.TRUE.equals(__nonBlocking.get()); }
Invoke a task with the calling thread, tagged to indicate that it will not block.
Params:
  • task – The task to invoke.
/** * Invoke a task with the calling thread, tagged to indicate * that it will not block. * * @param task The task to invoke. */
public static void invokeNonBlocking(Runnable task) { Boolean wasNonBlocking = __nonBlocking.get(); try { __nonBlocking.set(Boolean.TRUE); task.run(); } finally { __nonBlocking.set(wasNonBlocking); } } static InvocationType combine(InvocationType it1, InvocationType it2) { if (it1 != null && it2 != null) { if (it1 == it2) return it1; if (it1 == InvocationType.EITHER) return it2; if (it2 == InvocationType.EITHER) return it1; } return InvocationType.BLOCKING; }
Get the invocation type of an Object.
Params:
  • o – The object to check the invocation type of.
Returns:If the object is an Invocable, it is coerced and the getInvocationType() used, otherwise InvocationType.BLOCKING is returned.
/** * Get the invocation type of an Object. * * @param o The object to check the invocation type of. * @return If the object is an Invocable, it is coerced and the {@link #getInvocationType()} * used, otherwise {@link InvocationType#BLOCKING} is returned. */
public static InvocationType getInvocationType(Object o) { if (o instanceof Invocable) return ((Invocable)o).getInvocationType(); return InvocationType.BLOCKING; }
Returns:The InvocationType of this object
/** * @return The InvocationType of this object */
default InvocationType getInvocationType() { return InvocationType.BLOCKING; } }