package org.jboss.as.server;
import org.jboss.as.server.logging.ServerLogger;
import org.jboss.as.server.suspend.OperationListener;
import org.jboss.as.server.suspend.SuspendController;
import org.jboss.msc.service.Service;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.StartContext;
import org.jboss.msc.service.StartException;
import org.jboss.msc.service.StopContext;
import org.jboss.msc.value.InjectedValue;
/**
* A service that allows the server to wait until graceful shutdown is complete.
*
* This is mainly used to perform graceful shutdown in domain mode, to delay the System.exit() call
* until the server has suspended.
*
* @author Stuart Douglas
*/
public class GracefulShutdownService implements Service<GracefulShutdownService> {
public static final ServiceName SERVICE_NAME = ServiceName.JBOSS.append("server", "graceful-shutdown-service");
private final InjectedValue<SuspendController> suspendControllerInjectedValue = new InjectedValue<>();
private boolean suspend = false;
private boolean shuttingDown = false;
private final Object lock = new Object();
private final OperationListener listener = new OperationListener() {
@Override
public void suspendStarted() {
synchronized (lock) {
suspend = true;
}
}
@Override
public void complete() {
synchronized (lock) {
suspend = false;
lock.notifyAll();
}
}
@Override
public void cancelled() {
synchronized (lock) {
suspend = false;
lock.notifyAll();
}
}
@Override
public void timeout() {
synchronized (lock) {
suspend = false;
lock.notifyAll();
}
}
};
@Override
public void start(StartContext context) throws StartException {
suspendControllerInjectedValue.getValue().addListener(listener);
}
@Override
public void stop(StopContext context) {
suspendControllerInjectedValue.getValue().removeListener(listener);
}
public void startGracefulShutdown() {
synchronized (lock) {
shuttingDown = true;
}
}
public void awaitSuspend() {
synchronized (lock) {
while (suspend && shuttingDown) {
try {
lock.wait();
} catch (InterruptedException e) {
ServerLogger.AS_ROOT_LOGGER.debug("Exception waiting for graceful shutdown", e);
}
}
}
}
public InjectedValue<SuspendController> getSuspendControllerInjectedValue() {
return suspendControllerInjectedValue;
}
@Override
public GracefulShutdownService getValue() throws IllegalStateException, IllegalArgumentException {
return this;
}
}