com.github.ltsopensource.nio.handler.IoFuture Maven / Gradle / Ivy
package com.github.ltsopensource.nio.handler;
import com.github.ltsopensource.core.logger.Logger;
import com.github.ltsopensource.core.logger.LoggerFactory;
import com.github.ltsopensource.core.support.SystemClock;
import com.github.ltsopensource.remoting.Future;
import java.util.ArrayList;
import java.util.List;
/**
* @author Robert HG ([email protected]) on 1/30/16.
*/
public class IoFuture implements Future {
private static final Logger LOGGER = LoggerFactory.getLogger(IoFuture.class);
private static final long DEAD_LOCK_CHECK_INTERVAL = 5000L;
private boolean success = false;
private Throwable cause;
private String msg;
private List listeners;
private boolean done = false;
/**
* A lock used by the wait() method
*/
private final Object lock = this;
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public Throwable cause() {
return cause;
}
public void setCause(Throwable cause) {
this.cause = cause;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public boolean isDone() {
return done;
}
public void addListener(IoFutureListener listener) {
if (listener == null) {
return;
}
synchronized (lock) {
if (listeners == null) {
listeners = new ArrayList();
}
listeners.add(listener);
if (isDone()) {
complete(listener);
}
}
}
public void addListener(List listeners) {
if (listeners == null) {
return;
}
synchronized (lock) {
if (this.listeners == null) {
this.listeners = new ArrayList();
}
this.listeners.addAll(listeners);
if (isDone()) {
for (IoFutureListener listener : listeners) {
complete(listener);
}
}
}
}
public void removeListener(IoFutureListener listener) {
if (listener == null) {
return;
}
synchronized (lock) {
if (this.listeners != null) {
this.listeners.remove(listener);
}
}
}
public void notifyListeners() {
synchronized (lock) {
done = true;
if (this.listeners != null) {
for (IoFutureListener ioFutureListener : listeners) {
complete(ioFutureListener);
}
}
}
}
private void complete(IoFutureListener listener) {
try {
listener.operationComplete(this);
} catch (Exception e) {
LOGGER.error("notify listener {} error ", listener, e);
}
}
public boolean awaitUninterruptibly(long timeoutMillis) {
try {
return await0(timeoutMillis, false);
} catch (InterruptedException e) {
throw new InternalError();
}
}
private boolean await0(long timeoutMillis, boolean interruptable) throws InterruptedException {
if (isDone()) {
return true;
}
if (timeoutMillis <= 0) {
return isDone();
}
if (interruptable && Thread.interrupted()) {
throw new InterruptedException(toString());
}
long endTime = SystemClock.now() + timeoutMillis;
boolean interrupted = false;
synchronized (lock) {
if (isDone()) {
return true;
}
if (timeoutMillis <= 0) {
return isDone();
}
try {
for (; ; ) {
long timeOut = Math.min(timeoutMillis, DEAD_LOCK_CHECK_INTERVAL);
try {
lock.wait(timeOut);
} catch (InterruptedException e) {
if (interruptable) {
throw e;
} else {
interrupted = true;
}
}
if (isDone()) {
return true;
}
if (endTime < SystemClock.now()) {
return isDone();
}
}
} finally {
if (interrupted) {
Thread.currentThread().interrupt();
}
}
}
}
}