|
Java example source code file (UnixAsynchronousSocketChannelImpl.java)
The UnixAsynchronousSocketChannelImpl.java Java example source code
/*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.ch;
import java.nio.channels.*;
import java.nio.ByteBuffer;
import java.net.*;
import java.util.concurrent.*;
import java.io.IOException;
import java.io.FileDescriptor;
import java.security.AccessController;
import sun.net.NetHooks;
import sun.security.action.GetPropertyAction;
/**
* Unix implementation of AsynchronousSocketChannel
*/
class UnixAsynchronousSocketChannelImpl
extends AsynchronousSocketChannelImpl implements Port.PollableChannel
{
private final static NativeDispatcher nd = new SocketDispatcher();
private static enum OpType { CONNECT, READ, WRITE };
private static final boolean disableSynchronousRead;
static {
String propValue = AccessController.doPrivileged(
new GetPropertyAction("sun.nio.ch.disableSynchronousRead", "false"));
disableSynchronousRead = (propValue.length() == 0) ?
true : Boolean.valueOf(propValue);
}
private final Port port;
private final int fdVal;
// used to ensure that the context for I/O operations that complete
// ascynrhonously is visible to the pooled threads handling I/O events.
private final Object updateLock = new Object();
// pending connect (updateLock)
private boolean connectPending;
private CompletionHandler<Void,Object> connectHandler;
private Object connectAttachment;
private PendingFuture<Void,Object> connectFuture;
// pending remote address (stateLock)
private SocketAddress pendingRemote;
// pending read (updateLock)
private boolean readPending;
private boolean isScatteringRead;
private ByteBuffer readBuffer;
private ByteBuffer[] readBuffers;
private CompletionHandler<Number,Object> readHandler;
private Object readAttachment;
private PendingFuture<Number,Object> readFuture;
private Future<?> readTimer;
// pending write (updateLock)
private boolean writePending;
private boolean isGatheringWrite;
private ByteBuffer writeBuffer;
private ByteBuffer[] writeBuffers;
private CompletionHandler<Number,Object> writeHandler;
private Object writeAttachment;
private PendingFuture<Number,Object> writeFuture;
private Future<?> writeTimer;
UnixAsynchronousSocketChannelImpl(Port port)
throws IOException
{
super(port);
// set non-blocking
try {
IOUtil.configureBlocking(fd, false);
} catch (IOException x) {
nd.close(fd);
throw x;
}
this.port = port;
this.fdVal = IOUtil.fdVal(fd);
// add mapping from file descriptor to this channel
port.register(fdVal, this);
}
// Constructor for sockets created by UnixAsynchronousServerSocketChannelImpl
UnixAsynchronousSocketChannelImpl(Port port,
FileDescriptor fd,
InetSocketAddress remote)
throws IOException
{
super(port, fd, remote);
this.fdVal = IOUtil.fdVal(fd);
IOUtil.configureBlocking(fd, false);
try {
port.register(fdVal, this);
} catch (ShutdownChannelGroupException x) {
// ShutdownChannelGroupException thrown if we attempt to register a
// new channel after the group is shutdown
throw new IOException(x);
}
this.port = port;
}
@Override
public AsynchronousChannelGroupImpl group() {
return port;
}
// register events for outstanding I/O operations, caller already owns updateLock
private void updateEvents() {
assert Thread.holdsLock(updateLock);
int events = 0;
if (readPending)
events |= Port.POLLIN;
if (connectPending || writePending)
events |= Port.POLLOUT;
if (events != 0)
port.startPoll(fdVal, events);
}
// register events for outstanding I/O operations
private void lockAndUpdateEvents() {
synchronized (updateLock) {
updateEvents();
}
}
// invoke to finish read and/or write operations
private void finish(boolean mayInvokeDirect,
boolean readable,
boolean writable)
{
boolean finishRead = false;
boolean finishWrite = false;
boolean finishConnect = false;
// map event to pending result
synchronized (updateLock) {
if (readable && this.readPending) {
this.readPending = false;
finishRead = true;
}
if (writable) {
if (this.writePending) {
this.writePending = false;
finishWrite = true;
} else if (this.connectPending) {
this.connectPending = false;
finishConnect = true;
}
}
}
// complete the I/O operation. Special case for when channel is
// ready for both reading and writing. In that case, submit task to
// complete write if write operation has a completion handler.
if (finishRead) {
if (finishWrite)
finishWrite(false);
finishRead(mayInvokeDirect);
return;
}
if (finishWrite) {
finishWrite(mayInvokeDirect);
}
if (finishConnect) {
finishConnect(mayInvokeDirect);
}
}
/**
* Invoked by event handler thread when file descriptor is polled
*/
@Override
public void onEvent(int events, boolean mayInvokeDirect) {
boolean readable = (events & Port.POLLIN) > 0;
boolean writable = (events & Port.POLLOUT) > 0;
if ((events & (Port.POLLERR | Port.POLLHUP)) > 0) {
readable = true;
writable = true;
}
finish(mayInvokeDirect, readable, writable);
}
@Override
void implClose() throws IOException {
// remove the mapping
port.unregister(fdVal);
// close file descriptor
nd.close(fd);
// All outstanding I/O operations are required to fail
finish(false, true, true);
}
@Override
public void onCancel(PendingFuture<?,?> task) {
if (task.getContext() == OpType.CONNECT)
killConnect();
if (task.getContext() == OpType.READ)
killReading();
if (task.getContext() == OpType.WRITE)
killWriting();
}
// -- connect --
private void setConnected() throws IOException {
synchronized (stateLock) {
state = ST_CONNECTED;
localAddress = Net.localAddress(fd);
remoteAddress = (InetSocketAddress)pendingRemote;
}
}
private void finishConnect(boolean mayInvokeDirect) {
Throwable e = null;
try {
begin();
checkConnect(fdVal);
setConnected();
} catch (Throwable x) {
if (x instanceof ClosedChannelException)
x = new AsynchronousCloseException();
e = x;
} finally {
end();
}
if (e != null) {
// close channel if connection cannot be established
try {
close();
} catch (Throwable suppressed) {
e.addSuppressed(suppressed);
}
}
// invoke handler and set result
CompletionHandler<Void,Object> handler = connectHandler;
Object att = connectAttachment;
PendingFuture<Void,Object> future = connectFuture;
if (handler == null) {
future.setResult(null, e);
} else {
if (mayInvokeDirect) {
Invoker.invokeUnchecked(handler, att, null, e);
} else {
Invoker.invokeIndirectly(this, handler, att, null, e);
}
}
}
@Override
@SuppressWarnings("unchecked")
<A> Future
Other Java examples (source code examples)Here is a short list of links related to this Java UnixAsynchronousSocketChannelImpl.java source code file: |
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.