package xapi.process.api;
import java.util.concurrent.CancellationException;
import xapi.util.api.ErrorHandler;
import xapi.util.api.Pair;
import xapi.util.api.RemovalHandler;
import xapi.util.api.SuccessHandler;
/**
* In order to ease the apis of code shared with single-threaded environments,
* we create an Async abstraction that can function efficiently in a threadsafe
* enviro, while giving a useful "illusion of concurrency" when single-threaded.
*
* It does force a callback pattern onto code that may otherwise have been
* able to simple block and run in a nice procedural fashion,
* but it enables a more functional approach, that will scale much better.
*
* You do not wait for your work to be finished, you send the rest of work,
* and it is run for you when the given condition is satisfied
* (the owner of the lock calls {@link #signal()}.)
*
* @author "James X. Nelson (james@wetheinter.net)"
*
*/
public interface AsyncCondition {
/**
* Waits indefinitely for the given condition.
*
* @param onAcquire - A SuccessHandler to be notified when we are signalled.
* @return - A removal handler to cancel the wait if it hasn't already completed.
*
* If you want a deadline, use {@link #awaitWithDeadline(SuccessHandler, float)}
* If your SuccessHandler is also an {@link ErrorHandler}, you will receive
* a {@link CancellationException} when RemovalHandler.remove() is called.
*/
RemovalHandler await(SuccessHandler<Pair<AsyncLock, AsyncCondition>> onAcquire);
/**
* The same rules as {@link #await(SuccessHandler)}, but with a millisecond
* timeout that will share a notification pool, so a minimum of threads
* are needed to simply check deadlines and cancel / notify / continue.
*
* @param onAcquire - The success handler to call when we are signalled.
* @param millisToWait - A floating point number of milliseconds to wait.
* @return A {@link RemovalHandler} to cancel the operation.
* Does nothing if signal has already been called.
*/
RemovalHandler awaitWithDeadline(SuccessHandler<Pair<AsyncLock, AsyncCondition>> onAcquire
, float millisToWait);
/**
* Signals one waiting success handler, and returns true,
* -if the pool of waiting conditions was empty BEFORE calling onAcquire.onSuccess-
*
* @return - True is the waiting pool on SuccessHandlers had, at most one item
* in it when signal() is called. This can allow a flushing method to safely
* call while(signal()); to drain a condition.
*/
boolean signal();
}