2013-11-14 07:17:51 +00:00
|
|
|
package com.ryanmichela.sshd;
|
|
|
|
|
|
|
|
import java.util.concurrent.ExecutionException;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copyright 2013 Ryan Michela
|
|
|
|
*/
|
2019-11-24 05:53:58 +00:00
|
|
|
public abstract class Waitable<T> implements Runnable
|
|
|
|
{
|
2018-05-06 16:42:57 +00:00
|
|
|
|
2019-11-24 05:53:58 +00:00
|
|
|
private enum Status
|
|
|
|
{
|
2013-11-14 07:17:51 +00:00
|
|
|
WAITING,
|
|
|
|
RUNNING,
|
|
|
|
FINISHED,
|
|
|
|
}
|
2018-05-06 16:42:57 +00:00
|
|
|
|
2013-11-14 07:17:51 +00:00
|
|
|
Throwable t = null;
|
|
|
|
T value = null;
|
|
|
|
Status status = Status.WAITING;
|
|
|
|
|
2019-11-24 05:53:58 +00:00
|
|
|
public final void run()
|
|
|
|
{
|
|
|
|
synchronized (this)
|
|
|
|
{
|
|
|
|
if (status != Status.WAITING)
|
2013-11-14 07:17:51 +00:00
|
|
|
throw new IllegalStateException("Invalid state " + status);
|
2019-11-24 05:53:58 +00:00
|
|
|
|
2013-11-14 07:17:51 +00:00
|
|
|
status = Status.RUNNING;
|
|
|
|
}
|
2019-11-24 05:53:58 +00:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2013-11-14 07:17:51 +00:00
|
|
|
value = evaluate();
|
2019-11-24 05:53:58 +00:00
|
|
|
}
|
|
|
|
catch (Throwable t)
|
|
|
|
{
|
2013-11-14 07:17:51 +00:00
|
|
|
this.t = t;
|
2019-11-24 05:53:58 +00:00
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
synchronized (this)
|
|
|
|
{
|
2013-11-14 07:17:51 +00:00
|
|
|
status = Status.FINISHED;
|
|
|
|
this.notifyAll();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected abstract T evaluate();
|
|
|
|
|
2019-11-24 05:53:58 +00:00
|
|
|
public synchronized T get() throws InterruptedException, ExecutionException
|
|
|
|
{
|
|
|
|
while (status != Status.FINISHED)
|
2013-11-14 07:17:51 +00:00
|
|
|
this.wait();
|
2019-11-24 05:53:58 +00:00
|
|
|
|
|
|
|
if (t != null)
|
2013-11-14 07:17:51 +00:00
|
|
|
throw new ExecutionException(t);
|
2019-11-24 05:53:58 +00:00
|
|
|
|
2013-11-14 07:17:51 +00:00
|
|
|
return value;
|
|
|
|
}
|
|
|
|
}
|