blob: 020f23a902bf18e1bb58876df74109e27142c57c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ignite;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
/**
* This interface provides a rich API for working with condition objects
* associated with distributed reentrant locks.
* <p>
* <h1 class="header">Functionality</h1>
* IgniteCondition provides functionality similar to {@code java.util.concurrent.locks.Condition}.
*/
public interface IgniteCondition extends Condition {
/**
* Name of ignite condition.
*
* @return Name of ignite condition.
*/
public String name();
/**
* Causes the current thread to wait until it is signalled or
* {@linkplain Thread#interrupt interrupted}.
*
* <p>The lock associated with this {@code IgniteCondition} is atomically
* released and the current thread becomes disabled for thread scheduling
* purposes and lies dormant until <em>one</em> of six things happens:
* <ul>
* <li>Some other thread (on any node) invokes the {@link #signal} method for this
* {@code Condition} and the current thread happens to be chosen as the
* thread to be awakened; or
* <li>Some other thread (on any node) invokes the {@link #signalAll} method for this
* {@code Condition}; or
* <li>Some other thread {@linkplain Thread#interrupt interrupts} the
* current thread, and interruption of thread suspension is supported; or
* <li>Some other node in grid fails, and lock is created in non-failoverSafe mode; or
* <li>Local node is stopped; or
* <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
* </ul>
*
* <p>If lock is not broken (because of failure of lock owner node)
* in non-failoverSafe mode and local node is alive,
* before this method can return the current thread must
* re-acquire the lock associated with this condition. In all other cases
* when the thread returns it is <em>guaranteed</em> to hold this lock.
*
* <p>If the current thread:
* <ul>
* <li>has its interrupted status set on entry to this method; or
* <li>is {@linkplain Thread#interrupt interrupted} while waiting
* and interruption of thread suspension is supported,
* </ul>
* then {@link IgniteInterruptedException} is thrown and the current thread's
* interrupted status is cleared. It is not specified, in the first
* case, whether or not the test for interruption occurs before the lock
* is released.
*
* <p><b>Implementation Considerations</b>
*
* <p>The current thread is assumed to hold the lock associated with this
* {@code Condition} when this method is called. If not, an {@link IllegalMonitorStateException}
* will be thrown.
*
* @throws IgniteInterruptedException if the current thread is interrupted
* @throws IgniteException if the node stopped, or
* node owning the lock failed in non-failoversafe mode
*/
@Override void await() throws IgniteInterruptedException, IgniteException;
/**
* Causes the current thread to wait until it is signalled.
*
* <p>The lock associated with this condition is atomically
* released and the current thread becomes disabled for thread scheduling
* purposes and lies dormant until <em>one</em> of five things happens:
* <ul>
* <li>Some other thread invokes the {@link #signal} method for this
* {@code Condition} and the current thread happens to be chosen as the
* thread to be awakened; or
* <li>Some other thread invokes the {@link #signalAll} method for this
* {@code Condition}; or
* <li>Some other node in grid fails, and lock is created in non-failoverSafe mode; or
* <li>Local node is stopped; or
* <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
* </ul>
*
* <p>If lock is not broken (because of failure of lock owner node)
* in non-failoverSafe mode and local node is alive,
* before this method can return the current thread must
* re-acquire the lock associated with this condition. In all other cases,
* when the thread returns it is <em>guaranteed</em> to hold this lock.
*
* <p>If the current thread's interrupted status is set when it enters
* this method, or it is {@linkplain Thread#interrupt interrupted}
* while waiting, it will continue to wait until signalled. When it finally
* returns from this method its interrupted status will still
* be set.
*
* <p><b>Implementation Considerations</b>
*
* <p>The current thread is assumed to hold the lock associated with this
* {@code Condition} when this method is called. If not, an {@link IllegalMonitorStateException}
* will be thrown.
*
* @throws IgniteException if the node stopped, or
* node owning the lock failed in non-failoversafe mode
*/
@Override void awaitUninterruptibly() throws IgniteException;
/**
* Causes the current thread to wait until it is signalled or interrupted,
* or the specified waiting time elapses.
*
* <p>The lock associated with this condition is atomically
* released and the current thread becomes disabled for thread scheduling
* purposes and lies dormant until <em>one</em> of seven things happens:
* <ul>
* <li>Some other thread invokes the {@link #signal} method for this
* {@code Condition} and the current thread happens to be chosen as the
* thread to be awakened; or
* <li>Some other thread invokes the {@link #signalAll} method for this
* {@code Condition}; or
* <li>Some other thread {@linkplain Thread#interrupt interrupts} the
* current thread, and interruption of thread suspension is supported; or
* <li>The specified waiting time elapses; or
* <li>Some other node in grid fails, and lock is created in non-failoverSafe mode; or
* <li>Local node is stopped; or
* <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
* </ul>
*
* <p>If lock is not broken (because of failure of lock owner node)
* in non-failoverSafe mode and local node is alive,
* before this method can return the current thread must
* re-acquire the lock associated with this condition. When the
* thread returns it is <em>guaranteed</em> to hold this lock.
*
* <p>If the current thread:
* <ul>
* <li>has its interrupted status set on entry to this method; or
* <li>is {@linkplain Thread#interrupt interrupted} while waiting
* and interruption of thread suspension is supported,
* </ul>
* then {@link IgniteInterruptedException} is thrown and the current thread's
* interrupted status is cleared. It is not specified, in the first
* case, whether or not the test for interruption occurs before the lock
* is released.
*
* <p>The method returns an estimate of the number of nanoseconds
* remaining to wait given the supplied {@code nanosTimeout}
* value upon return, or a value less than or equal to zero if it
* timed out. This value can be used to determine whether and how
* long to re-wait in cases where the wait returns but an awaited
* condition still does not hold. Typical uses of this method take
* the following form:
*
* <pre> {@code
* boolean aMethod(long timeout, TimeUnit unit) {
* long nanos = unit.toNanos(timeout);
* lock.lock();
* try {
* while (!conditionBeingWaitedFor()) {
* if (nanos <= 0L)
* return false;
* nanos = theCondition.awaitNanos(nanos);
* }
* // ...
* } finally {
* lock.unlock();
* }
* }}</pre>
*
* <p>Design note: This method requires a nanosecond argument so
* as to avoid truncation errors in reporting remaining times.
* Such precision loss would make it difficult for programmers to
* ensure that total waiting times are not systematically shorter
* than specified when re-waits occur.
*
* <p><b>Implementation Considerations</b>
*
* <p>The current thread is assumed to hold the lock associated with this
* {@code Condition} when this method is called. If not, an {@link IllegalMonitorStateException}
* will be thrown.
*
* @param nanosTimeout the maximum time to wait, in nanoseconds
* @return an estimate of the {@code nanosTimeout} value minus
* the time spent waiting upon return from this method.
* A positive value may be used as the argument to a
* subsequent call to this method to finish waiting out
* the desired time. A value less than or equal to zero
* indicates that no time remains.
* @throws IgniteInterruptedException if the current thread is interrupted
* @throws IgniteException if the node stopped, or
* node owning the lock failed in non-failoversafe mode
*/
@Override long awaitNanos(long nanosTimeout) throws IgniteInterruptedException, IgniteException;
/**
* Causes the current thread to wait until it is signalled or interrupted,
* or the specified waiting time elapses. This method is behaviorally
* equivalent to:
* <pre> {@code awaitNanos(unit.toNanos(time)) > 0}</pre>
*
* @param time the maximum time to wait
* @param unit the time unit of the {@code time} argument
* @return {@code false} if the waiting time detectably elapsed
* before return from the method, else {@code true}
* @throws IgniteInterruptedException if the current thread is interrupted
* @throws IgniteException if the node stopped, or
* node owning the lock failed in non-failoversafe mode
*/
@Override boolean await(long time, TimeUnit unit) throws IgniteInterruptedException, IgniteException;
/**
* Causes the current thread to wait until it is signalled or interrupted,
* or the specified deadline elapses.
*
* <p>The lock associated with this condition is atomically
* released and the current thread becomes disabled for thread scheduling
* purposes and lies dormant until <em>one</em> of seven things happens:
* <ul>
* <li>Some other thread invokes the {@link #signal} method for this
* {@code Condition} and the current thread happens to be chosen as the
* thread to be awakened; or
* <li>Some other thread invokes the {@link #signalAll} method for this
* {@code Condition}; or
* <li>Some other thread {@linkplain Thread#interrupt interrupts} the
* current thread, and interruption of thread suspension is supported; or
* <li>Some other node in grid fails, and lock is created in non-failoverSafe mode; or
* <li>Local node is stopped; or
* <li>The specified deadline elapses; or
* <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
* </ul>
*
* <p>If lock is not broken (because of failure of lock owner node)
* in non-failoverSafe mode and local node is alive,
* before this method can return the current thread must
* re-acquire the lock associated with this condition. When the
* thread returns it is <em>guaranteed</em> to hold this lock.
*
* <p>If the current thread:
* <ul>
* <li>has its interrupted status set on entry to this method; or
* <li>is {@linkplain Thread#interrupt interrupted} while waiting
* and interruption of thread suspension is supported,
* </ul>
* then {@link IgniteInterruptedException} is thrown and the current thread's
* interrupted status is cleared. It is not specified, in the first
* case, whether or not the test for interruption occurs before the lock
* is released.
*
* <p>The return value indicates whether the deadline has elapsed,
* which can be used as follows:
* <pre> {@code
* boolean aMethod(Date deadline) {
* boolean stillWaiting = true;
* lock.lock();
* try {
* while (!conditionBeingWaitedFor()) {
* if (!stillWaiting)
* return false;
* stillWaiting = theCondition.awaitUntil(deadline);
* }
* // ...
* } finally {
* lock.unlock();
* }
* }}</pre>
*
* <p><b>Implementation Considerations</b>
*
* <p>The current thread is assumed to hold the lock associated with this
* {@code Condition} when this method is called. If not, an {@link IllegalMonitorStateException}
* will be thrown.
*
* @param deadline the absolute time to wait until
* @return {@code false} if the deadline has elapsed upon return, else
* {@code true}
* @throws IgniteInterruptedException if the current thread is interrupted
* (and interruption of thread suspension is supported)
* @throws IgniteException if the node stopped, or
* node owning the lock failed in non-failoversafe mode
*/
@Override boolean awaitUntil(Date deadline) throws IgniteInterruptedException, IgniteException;
/**
* Wakes up one waiting thread.
*
* <p>If any threads are waiting on this condition then one
* is selected for waking up. That thread must then re-acquire the
* lock before returning from {@code await}.
*
* <p><b>Implementation Considerations</b>
*
* <p>The current thread is assumed to hold the lock associated with this
* {@code Condition} when this method is called. If not, an {@link IllegalMonitorStateException}
* will be thrown.
*
* @throws IgniteException if node is stopped or
* node owning the lock failed in non-failoversafe mode
*/
@Override void signal() throws IgniteException;
/**
* Wakes up all waiting threads.
*
* <p>If any threads are waiting on this condition then they are
* all woken up. Each thread must re-acquire the lock before it can
* return from {@code await}.
*
* <p><b>Implementation Considerations</b>
*
* <p>The current thread is assumed to hold the lock associated with this
* {@code Condition} when this method is called. If not, an {@link IllegalMonitorStateException}
* will be thrown.
*
* @throws IgniteException if node is stopped or
* node owning the lock failed in non-failoversafe mode
*/
@Override void signalAll() throws IgniteException;
}