Skip to content

Commit

Permalink
Fixes #7240 - Clarify and javadoc InvocationType. (#7241)
Browse files Browse the repository at this point in the history
* Fixes #7240 - Clarify and javadoc InvocationType.

Signed-off-by: Simone Bordet <[email protected]>
  • Loading branch information
sbordet authored Dec 9, 2021
1 parent 05d9feb commit b220311
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

import java.util.concurrent.Callable;

import org.eclipse.jetty.util.Callback;

/**
* <p>A task (typically either a {@link Runnable} or {@link Callable}
* that declares how it will behave when invoked:</p>
Expand All @@ -33,9 +35,42 @@ public interface Invocable
{
static ThreadLocal<Boolean> __nonBlocking = new ThreadLocal<>();

/**
* <p>The behavior of an {@link Invocable} when it is invoked.</p>
* <p>Typically, {@link Runnable}s or {@link Callback}s declare their
* invocation type; this information is then used by the code that should
* invoke the {@code Runnable} or {@code Callback} to decide whether to
* invoke it directly, or submit it to a thread pool to be invoked by
* a different thread.</p>
*/
enum InvocationType
{
BLOCKING, NON_BLOCKING, EITHER
/**
* <p>Invoking the {@link Invocable} may block the invoker thread,
* and the invocation may be performed immediately (possibly blocking
* the invoker thread) or deferred to a later time, for example
* by submitting the {@code Invocable} to a thread pool.</p>
* <p>This invocation type is suitable for {@code Invocable}s that
* call application code, for example to process an HTTP request.</p>
*/
BLOCKING,
/**
* <p>Invoking the {@link Invocable} does not block the invoker thread,
* and the invocation may be performed immediately in the invoker thread.</p>
* <p>This invocation type is suitable for {@code Invocable}s that
* call implementation code that is guaranteed to never block the
* invoker thread.</p>
*/
NON_BLOCKING,
/**
* <p>Invoking the {@link Invocable} may block the invoker thread,
* but the invocation cannot be deferred to a later time, differently
* from {@link #BLOCKING}.</p>
* <p>This invocation type is suitable for {@code Invocable}s that
* themselves perform the non-deferrable action in a non-blocking way,
* thus advancing a possibly stalled system.</p>
*/
EITHER
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,26 +296,26 @@ private SubStrategy selectSubStrategy(Runnable task, boolean nonBlocking)
case EITHER:
// The produced task may be run either as blocking or non blocking.

// If the calling producing thread may also block
if (!nonBlocking)
// If the calling producing thread is already non-blocking, use PC.
if (nonBlocking)
return SubStrategy.PRODUCE_CONSUME;

// Take the lock to atomically check if a pending producer is available.
try (AutoLock l = _lock.lock())
{
// Take the lock to atomically check if a pending producer is available.
try (AutoLock l = _lock.lock())
// If a pending producer is available or one can be started
if (_pending || _tryExecutor.tryExecute(_runPendingProducer))
{
// If a pending producer is available or one can be started
if (_pending || _tryExecutor.tryExecute(_runPendingProducer))
{
// use EPC: The producer directly consumes the task, which may block
// and then races with the pending producer to resume production.
_pending = true;
_state = State.IDLE;
return SubStrategy.EXECUTE_PRODUCE_CONSUME;
}
// Use EPC: the producer directly consumes the task, which may block
// and then races with the pending producer to resume production.
_pending = true;
_state = State.IDLE;
return SubStrategy.EXECUTE_PRODUCE_CONSUME;
}
}

// otherwise use PIC: The producer consumers the task in non-blocking mode
// and then resumes production.
// Otherwise use PIC: the producer consumes the task
// in non-blocking mode and then resumes production.
return SubStrategy.PRODUCE_INVOKE_CONSUME;

case BLOCKING:
Expand Down

0 comments on commit b220311

Please sign in to comment.