org.apache.sshd.common.Closeable Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.sshd.common;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.nio.channels.Channel;
import java.util.concurrent.TimeUnit;
import org.apache.sshd.common.future.CloseFuture;
import org.apache.sshd.common.future.SshFutureListener;
/**
* A {@code Closeable} is a resource that can be closed.
* The close method is invoked to release resources that the object is
* holding. The user can pre-register listeners to be notified
* when resource close is completed (successfully or otherwise)
*
* @author Apache MINA SSHD Project
*/
public interface Closeable extends Channel {
/**
* Timeout (milliseconds) for waiting on a {@link CloseFuture} to successfully
* complete its action.
* @see #DEFAULT_CLOSE_WAIT_TIMEOUT
*/
String CLOSE_WAIT_TIMEOUT = "sshd-close-wait-time";
/**
* Default value for {@link #CLOSE_WAIT_TIMEOUT} if none specified
*/
long DEFAULT_CLOSE_WAIT_TIMEOUT = TimeUnit.SECONDS.toMillis(15L);
/**
* Close this resource asynchronously and return a future.
* Resources support two closing modes: a graceful mode
* which will cleanly close the resource and an immediate mode
* which will close the resources abruptly.
*
* @param immediately true
if the resource should be shut down abruptly,
* false
for a graceful close
* @return a {@link CloseFuture} representing the close request
*/
CloseFuture close(boolean immediately);
/**
* Pre-register a listener to be informed when resource is closed. If
* resource is already closed, the listener will be invoked immediately
* and not registered for future notification
*
* @param listener The notification {@link SshFutureListener} - never {@code null}
*/
void addCloseFutureListener(SshFutureListener listener);
/**
* Remove a pre-registered close event listener
*
* @param listener The register {@link SshFutureListener} - never {@code null}.
* Ignored if not registered or resource already closed
*/
void removeCloseFutureListener(SshFutureListener listener);
/**
* Returns true
if this object has been closed.
*
* @return true
if closing
*/
boolean isClosed();
/**
* Returns true
if the {@link #close(boolean)} method
* has been called. Note that this method will return true
* even if this {@link #isClosed()} returns true
.
*
* @return true
if closing
*/
boolean isClosing();
@Override
default boolean isOpen() {
return !(isClosed() || isClosing());
}
@Override
default void close() throws IOException {
Closeable.close(this);
}
static long getMaxCloseWaitTime(PropertyResolver resolver) {
return (resolver == null)
? DEFAULT_CLOSE_WAIT_TIMEOUT
: resolver.getLongProperty(CLOSE_WAIT_TIMEOUT, DEFAULT_CLOSE_WAIT_TIMEOUT);
}
static void close(Closeable closeable) throws IOException {
if (closeable == null) {
return;
}
if ((!closeable.isClosed()) && (!closeable.isClosing())) {
CloseFuture future = closeable.close(true);
long maxWait = (closeable instanceof PropertyResolver)
? getMaxCloseWaitTime((PropertyResolver) closeable)
: DEFAULT_CLOSE_WAIT_TIMEOUT;
boolean successful = future.await(maxWait);
if (!successful) {
throw new SocketTimeoutException("Failed to receive closure confirmation within " + maxWait + " millis");
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy