org.xnio.XnioIoThread Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xnio-api Show documentation
Show all versions of xnio-api Show documentation
The API JAR of the XNIO project
/*
* JBoss, Home of Professional Open Source
*
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* Licensed 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.xnio;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import org.wildfly.common.Assert;
import org.xnio.channels.AssembledStreamChannel;
import org.xnio.channels.BoundChannel;
import org.xnio.channels.StreamChannel;
import org.xnio.channels.StreamSinkChannel;
import org.xnio.channels.StreamSourceChannel;
import static org.xnio._private.Messages.msg;
/**
* An XNIO thread.
*
* @author David M. Lloyd
*/
@SuppressWarnings("unused")
public abstract class XnioIoThread extends Thread implements XnioExecutor, XnioIoFactory {
private static final InetSocketAddress ANY_INET_ADDRESS = new InetSocketAddress(0);
private final XnioWorker worker;
private final int number;
/**
* Construct a new instance.
*
* @param worker the XNIO worker to associate with
* @param number the thread number
*/
protected XnioIoThread(final XnioWorker worker, final int number) {
this.number = number;
this.worker = worker;
}
/**
* Construct a new instance.
*
* @param worker the XNIO worker to associate with
* @param number the thread number
* @param name the thread name
*/
protected XnioIoThread(final XnioWorker worker, final int number, final String name) {
super(name);
this.number = number;
this.worker = worker;
}
/**
* Construct a new instance.
*
* @param worker the XNIO worker to associate with
* @param number the thread number
* @param group the thread group
* @param name the thread name
*/
protected XnioIoThread(final XnioWorker worker, final int number, final ThreadGroup group, final String name) {
super(group, name);
this.number = number;
this.worker = worker;
}
/**
* Construct a new instance.
*
* @param worker the XNIO worker to associate with
* @param number the thread number
* @param group the thread group
* @param name the thread name
* @param stackSize the thread stack size
*/
protected XnioIoThread(final XnioWorker worker, final int number, final ThreadGroup group, final String name, final long stackSize) {
super(group, null, name, stackSize);
this.number = number;
this.worker = worker;
}
/**
* Get the current XNIO thread. If the current thread is not an XNIO thread, {@code null} is returned.
*
* @return the current XNIO thread
*/
public static XnioIoThread currentThread() {
final Thread thread = Thread.currentThread();
if (thread instanceof XnioIoThread) {
return (XnioIoThread) thread;
} else {
return null;
}
}
/**
* Get the current XNIO thread. If the current thread is not an XNIO thread, an {@link IllegalStateException} is
* thrown.
*
* @return the current XNIO thread
* @throws IllegalStateException if the current thread is not an XNIO thread
*/
public static XnioIoThread requireCurrentThread() throws IllegalStateException {
final XnioIoThread thread = currentThread();
if (thread == null) {
throw msg.xnioThreadRequired();
}
return thread;
}
/**
* Get the number of this thread. In each XNIO worker, every IO thread is given a unique, sequential number.
*
* @return the number of this thread
*/
public int getNumber() {
return number;
}
/**
* Get the XNIO worker associated with this thread.
*
* @return the XNIO worker
*/
public XnioWorker getWorker() {
return worker;
}
public IoFuture acceptStreamConnection(SocketAddress destination, ChannelListener super StreamConnection> openListener, ChannelListener super BoundChannel> bindListener, OptionMap optionMap) {
if (destination == null) {
throw msg.nullParameter("destination");
}
if (destination instanceof InetSocketAddress) {
return acceptTcpStreamConnection((InetSocketAddress) destination, openListener, bindListener, optionMap);
} else if (destination instanceof LocalSocketAddress) {
return acceptLocalStreamConnection((LocalSocketAddress) destination, openListener, bindListener, optionMap);
} else {
throw msg.badSockType(destination.getClass());
}
}
/**
* Implementation helper method to accept a local (UNIX domain) stream connection.
*
* @param destination the destination (bind) address
* @param openListener the listener which will be notified when the channel is open, or {@code null} for none
* @param bindListener the listener which will be notified when the acceptor is bound, or {@code null} for none
* @param optionMap the option map
*
* @return the future connection
*/
protected IoFuture acceptLocalStreamConnection(LocalSocketAddress destination, ChannelListener super StreamConnection> openListener, ChannelListener super BoundChannel> bindListener, OptionMap optionMap) {
throw msg.unsupported("acceptLocalStreamConnection");
}
/**
* Implementation helper method to accept a TCP connection.
*
* @param destination the destination (bind) address
* @param openListener the listener which will be notified when the channel is open, or {@code null} for none
* @param bindListener the listener which will be notified when the acceptor is bound, or {@code null} for none
* @param optionMap the option map
*
* @return the future connection
*/
protected IoFuture acceptTcpStreamConnection(InetSocketAddress destination, ChannelListener super StreamConnection> openListener, ChannelListener super BoundChannel> bindListener, OptionMap optionMap) {
throw msg.unsupported("acceptTcpStreamConnection");
}
public IoFuture openMessageConnection(final SocketAddress destination, final ChannelListener super MessageConnection> openListener, final OptionMap optionMap) {
if (destination == null) {
throw msg.nullParameter("destination");
}
if (destination instanceof LocalSocketAddress) {
return openLocalMessageConnection(Xnio.ANY_LOCAL_ADDRESS, (LocalSocketAddress) destination, openListener, optionMap);
} else {
throw msg.badSockType(destination.getClass());
}
}
public IoFuture acceptMessageConnection(final SocketAddress destination, final ChannelListener super MessageConnection> openListener, final ChannelListener super BoundChannel> bindListener, final OptionMap optionMap) {
if (destination == null) {
throw msg.nullParameter("destination");
}
if (destination instanceof LocalSocketAddress) {
return acceptLocalMessageConnection((LocalSocketAddress) destination, openListener, bindListener, optionMap);
} else {
throw msg.badSockType(destination.getClass());
}
}
/**
* Implementation helper method to accept a local (UNIX domain) datagram connection.
*
* @param destination the destination (bind) address
* @param openListener the listener which will be notified when the channel is open, or {@code null} for none
* @param bindListener the listener which will be notified when the acceptor is bound, or {@code null} for none
* @param optionMap the option map
*
* @return the future connection
*/
protected IoFuture acceptLocalMessageConnection(LocalSocketAddress destination, ChannelListener super MessageConnection> openListener, ChannelListener super BoundChannel> bindListener, OptionMap optionMap) {
throw msg.unsupported("acceptLocalMessageConnection");
}
public IoFuture openStreamConnection(SocketAddress destination, ChannelListener super StreamConnection> openListener, OptionMap optionMap) {
Assert.checkNotNullParam("destination", destination);
if (destination instanceof InetSocketAddress) {
return internalOpenTcpStreamConnection((InetSocketAddress) destination, openListener, null, optionMap);
} else if (destination instanceof LocalSocketAddress) {
return openLocalStreamConnection(Xnio.ANY_LOCAL_ADDRESS, (LocalSocketAddress) destination, openListener, null, optionMap);
} else {
throw msg.badSockType(destination.getClass());
}
}
public IoFuture openStreamConnection(SocketAddress destination, ChannelListener super StreamConnection> openListener, ChannelListener super BoundChannel> bindListener, OptionMap optionMap) {
Assert.checkNotNullParam("destination", destination);
if (destination instanceof InetSocketAddress) {
return internalOpenTcpStreamConnection((InetSocketAddress) destination, openListener, bindListener, optionMap);
} else if (destination instanceof LocalSocketAddress) {
return openLocalStreamConnection(Xnio.ANY_LOCAL_ADDRESS, (LocalSocketAddress) destination, openListener, bindListener, optionMap);
} else {
throw msg.badSockType(destination.getClass());
}
}
private IoFuture internalOpenTcpStreamConnection(InetSocketAddress destination, ChannelListener super StreamConnection> openListener, ChannelListener super BoundChannel> bindListener, OptionMap optionMap) {
if (destination.isUnresolved()) {
try {
destination = new InetSocketAddress(InetAddress.getByName(destination.getHostString()), destination.getPort());
} catch (UnknownHostException e) {
return new FailedIoFuture<>(e);
}
}
InetSocketAddress bindAddress = getWorker().getBindAddressTable().get(destination.getAddress());
return openTcpStreamConnection(bindAddress, destination, openListener, bindListener, optionMap);
}
public IoFuture openStreamConnection(SocketAddress bindAddress, SocketAddress destination, ChannelListener super StreamConnection> openListener, ChannelListener super BoundChannel> bindListener, OptionMap optionMap) {
Assert.checkNotNullParam("bindAddress", bindAddress);
Assert.checkNotNullParam("destination", destination);
if (bindAddress.getClass() != destination.getClass()) {
throw msg.mismatchSockType(bindAddress.getClass(), destination.getClass());
}
if (destination instanceof InetSocketAddress) {
final InetSocketAddress configuredAddress = ANY_INET_ADDRESS.equals(bindAddress) ? getWorker().getBindAddressTable().get(((InetSocketAddress) destination).getAddress()) : null;
bindAddress = configuredAddress != null ? configuredAddress : bindAddress;
return openTcpStreamConnection((InetSocketAddress) bindAddress, (InetSocketAddress) destination, openListener, bindListener, optionMap);
} else if (destination instanceof LocalSocketAddress) {
return openLocalStreamConnection((LocalSocketAddress) bindAddress, (LocalSocketAddress) destination, openListener, bindListener, optionMap);
} else {
throw msg.badSockType(destination.getClass());
}
}
/**
* Implementation helper method to connect to a TCP server.
*
* @param bindAddress the bind address
* @param destinationAddress the destination address
* @param openListener the listener which will be notified when the channel is open, or {@code null} for none
* @param bindListener the listener which will be notified when the channel is bound, or {@code null} for none
* @param optionMap the option map
* @return the future result of this operation
*/
protected IoFuture openTcpStreamConnection(InetSocketAddress bindAddress, InetSocketAddress destinationAddress, ChannelListener super StreamConnection> openListener, ChannelListener super BoundChannel> bindListener, OptionMap optionMap) {
throw msg.unsupported("openTcpStreamConnection");
}
/**
* Implementation helper method to connect to a local (UNIX domain) server.
*
* @param bindAddress the bind address
* @param destinationAddress the destination address
* @param openListener the listener which will be notified when the channel is open, or {@code null} for none
* @param bindListener the listener which will be notified when the channel is bound, or {@code null} for none
* @param optionMap the option map
* @return the future result of this operation
*/
protected IoFuture openLocalStreamConnection(LocalSocketAddress bindAddress, LocalSocketAddress destinationAddress, ChannelListener super StreamConnection> openListener, ChannelListener super BoundChannel> bindListener, OptionMap optionMap) {
throw msg.unsupported("openLocalStreamConnection");
}
/**
* Implementation helper method to connect to a local (UNIX domain) server.
*
* @param bindAddress the bind address
* @param destinationAddress the destination address
* @param openListener the listener which will be notified when the channel is open, or {@code null} for none
* @param optionMap the option map
* @return the future result of this operation
*/
protected IoFuture openLocalMessageConnection(LocalSocketAddress bindAddress, LocalSocketAddress destinationAddress, ChannelListener super MessageConnection> openListener, OptionMap optionMap) {
throw msg.unsupported("openLocalMessageConnection");
}
public ChannelPipe createFullDuplexPipe() throws IOException {
final ChannelPipe connection = createFullDuplexPipeConnection();
final StreamChannel left = new AssembledStreamChannel(connection.getLeftSide(), connection.getLeftSide().getSourceChannel(), connection.getLeftSide().getSinkChannel());
final StreamChannel right = new AssembledStreamChannel(connection.getRightSide(), connection.getRightSide().getSourceChannel(), connection.getRightSide().getSinkChannel());
return new ChannelPipe(left, right);
}
public ChannelPipe createFullDuplexPipeConnection() throws IOException {
return createFullDuplexPipeConnection(this);
}
public ChannelPipe createHalfDuplexPipe() throws IOException {
return createHalfDuplexPipe(this);
}
public ChannelPipe createFullDuplexPipeConnection(final XnioIoFactory peer) throws IOException {
throw msg.unsupported("createFullDuplexPipeConnection");
}
public ChannelPipe createHalfDuplexPipe(final XnioIoFactory peer) throws IOException {
throw msg.unsupported("createHalfDuplexPipe");
}
}