mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-08 16:18:05 +03:00
149 lines
4.7 KiB
Java
149 lines
4.7 KiB
Java
/*
|
|
* Copyright (C)2009 - SSHJ Contributors
|
|
*
|
|
* Licensed 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 net.schmizz.concurrent;
|
|
|
|
import net.schmizz.sshj.common.LoggerFactory;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.concurrent.locks.ReentrantLock;
|
|
|
|
/**
|
|
* An event can be set, cleared, or awaited, similar to Python's {@code threading.event}. The key difference is that a
|
|
* waiter may be delivered an exception of parameterized type {@code T}.
|
|
* <p/>
|
|
* Uses {@link Promise} under the hood.
|
|
*/
|
|
public class Event<T extends Throwable> {
|
|
|
|
private static final Object SOME = new Object() {
|
|
@Override
|
|
public String toString() {
|
|
return "SOME";
|
|
}
|
|
};
|
|
|
|
private final Promise<Object, T> promise;
|
|
|
|
/**
|
|
* Creates this event with given {@code name} and exception {@code chainer}. Allocates a new {@link
|
|
* java.util.concurrent.locks.Lock Lock} object for this event.
|
|
*
|
|
* @param name name of this event
|
|
* @param chainer {@link ExceptionChainer} that will be used for chaining exceptions
|
|
*/
|
|
public Event(String name, ExceptionChainer<T> chainer, LoggerFactory loggerFactory) {
|
|
promise = new Promise<Object, T>(name, chainer, loggerFactory);
|
|
}
|
|
|
|
/**
|
|
* Creates this event with given {@code name}, exception {@code chainer}, and associated {@code lock}.
|
|
*
|
|
* @param name name of this event
|
|
* @param chainer {@link ExceptionChainer} that will be used for chaining exceptions
|
|
* @param lock lock to use
|
|
*/
|
|
public Event(String name, ExceptionChainer<T> chainer, ReentrantLock lock, LoggerFactory loggerFactory) {
|
|
promise = new Promise<Object, T>(name, chainer, lock, loggerFactory);
|
|
}
|
|
|
|
/** Sets this event to be {@code true}. Short for {@code set(true)}. */
|
|
public void set() {
|
|
promise.deliver(SOME);
|
|
}
|
|
|
|
/** Clear this event. A cleared event {@code !isSet()}. */
|
|
public void clear() {
|
|
promise.clear();
|
|
}
|
|
|
|
/** Deliver the error {@code t} (after chaining) to any present or future waiters. */
|
|
public void deliverError(Throwable t) {
|
|
promise.deliverError(t);
|
|
}
|
|
|
|
/**
|
|
* @return whether this event is in a 'set' state. An event is set by a call to {@link #set} or {@link
|
|
* #deliverError}
|
|
*/
|
|
public boolean isSet() {
|
|
return promise.isDelivered();
|
|
}
|
|
|
|
/**
|
|
* Await this event to have a definite {@code true} or {@code false} value.
|
|
*
|
|
* @throws T if another thread meanwhile informs this event of an error
|
|
*/
|
|
public void await()
|
|
throws T {
|
|
promise.retrieve();
|
|
}
|
|
|
|
/**
|
|
* Await this event to have a definite {@code true} or {@code false} value, for {@code timeout} duration.
|
|
*
|
|
* @param timeout timeout
|
|
* @param unit the time unit for the timeout
|
|
*
|
|
* @throws T if another thread meanwhile informs this event of an error, or timeout expires
|
|
*/
|
|
public void await(long timeout, TimeUnit unit)
|
|
throws T {
|
|
promise.retrieve(timeout, unit);
|
|
}
|
|
|
|
/**
|
|
* Await this event to have a definite {@code true} or {@code false} value, for {@code timeout} duration.
|
|
* <p/>
|
|
* If the definite value is not available when the timeout expires, returns {@code false}.
|
|
*
|
|
* @param timeout timeout
|
|
* @param unit the time unit for the timeout
|
|
*
|
|
* @throws T if another thread meanwhile informs this event of an error
|
|
*/
|
|
public boolean tryAwait(long timeout, TimeUnit unit)
|
|
throws T {
|
|
return promise.tryRetrieve(timeout, unit) != null;
|
|
}
|
|
|
|
/** @return whether there are any threads waiting on this event to be set. */
|
|
public boolean hasWaiters() {
|
|
return promise.hasWaiters();
|
|
}
|
|
|
|
/** @return whether this event is in an error state i.e. has been delivered an error. */
|
|
public boolean inError() {
|
|
return promise.inError();
|
|
}
|
|
|
|
/** Acquire the lock associated with this event. */
|
|
public void lock() {
|
|
promise.lock();
|
|
}
|
|
|
|
/** Release the lock associated with this event. */
|
|
public void unlock() {
|
|
promise.unlock();
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return promise.toString();
|
|
}
|
|
|
|
}
|