All Downloads are FREE. Search and download functionalities are using the official Maven repository.

java.nio.channels.spi.AbstractInterruptibleChannel 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 java.nio.channels.spi;

import java.io.IOException;
import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.Channel;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.InterruptibleChannel;

/**
 * {@code AbstractInterruptibleChannel} is the root class for interruptible
 * channels.
 * 

* The basic usage pattern for an interruptible channel is to invoke * {@code begin()} before any I/O operation that potentially blocks * indefinitely, then {@code end(boolean)} after completing the operation. The * argument to the {@code end} method should indicate if the I/O operation has * actually completed so that any change may be visible to the invoker. */ public abstract class AbstractInterruptibleChannel implements Channel, InterruptibleChannel { private volatile boolean closed = false; volatile boolean interrupted = false; private final Runnable interruptAndCloseRunnable = new Runnable() { @Override public void run() { try { interrupted = true; AbstractInterruptibleChannel.this.close(); } catch (IOException ignored) { } } }; protected AbstractInterruptibleChannel() { } @Override public synchronized final boolean isOpen() { return !closed; } /** * Closes an open channel. If the channel is already closed then this method * has no effect, otherwise it closes the receiver via the * {@code implCloseChannel} method. *

* If an attempt is made to perform an operation on a closed channel then a * {@link java.nio.channels.ClosedChannelException} is thrown. *

* If multiple threads attempt to simultaneously close a channel, then only * one thread will run the closure code and the others will be blocked until * the first one completes. * * @throws IOException * if a problem occurs while closing this channel. * @see java.nio.channels.Channel#close() */ @Override public final void close() throws IOException { if (!closed) { synchronized (this) { if (!closed) { closed = true; implCloseChannel(); } } } } /** * Indicates the beginning of a code section that includes an I/O operation * that is potentially blocking. After this operation, the application * should invoke the corresponding {@code end(boolean)} method. */ protected final void begin() { Thread.currentThread().pushInterruptAction$(interruptAndCloseRunnable); } /** * Indicates the end of a code section that has been started with * {@code begin()} and that includes a potentially blocking I/O operation. * * @param success * pass {@code true} if the blocking operation has succeeded and * has had a noticeable effect; {@code false} otherwise. * @throws AsynchronousCloseException * if this channel is closed by another thread while this method * is executing. * @throws ClosedByInterruptException * if another thread interrupts the calling thread while this * method is executing. */ protected final void end(boolean success) throws AsynchronousCloseException { Thread.currentThread().popInterruptAction$(interruptAndCloseRunnable); if (interrupted) { interrupted = false; throw new ClosedByInterruptException(); } if (!success && closed) { throw new AsynchronousCloseException(); } } /** * Implements the channel closing behavior. *

* Closes the channel with a guarantee that the channel is not currently * closed through another invocation of {@code close()} and that the method * is thread-safe. *

* Any outstanding threads blocked on I/O operations on this channel must be * released with either a normal return code, or by throwing an * {@code AsynchronousCloseException}. * * @throws IOException * if a problem occurs while closing the channel. */ protected abstract void implCloseChannel() throws IOException; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy