| /* |
| * 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 "<em>spurious wakeup</em>" 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 "<em>spurious wakeup</em>" 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 "<em>spurious wakeup</em>" 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 "<em>spurious wakeup</em>" 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; |
| } |