/* * Copyright 2012-2015, the original author or authors. * * 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 com.flipkart.phantom.netty.uds; import org.jboss.netty.channel.*; import org.jboss.netty.channel.socket.DefaultSocketChannelConfig; import org.jboss.netty.channel.socket.SocketChannel; import org.jboss.netty.channel.socket.SocketChannelConfig; import java.io.OutputStream; import java.io.PushbackInputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; /** * Based on: org.jboss.netty.channel.socket.oio.OioSocketChannel * OIO package modified to work for Unix Domain Sockets instead of ServerSocket. * * @author devashishshankar * @version 1.0, 19th April 2013 */ abstract class OioSocketChannel extends AbstractChannel implements SocketChannel { final Socket socket; final Object interestOpsLock = new Object(); private final SocketChannelConfig config; volatile Thread workerThread; private volatile InetSocketAddress localAddress; private volatile InetSocketAddress remoteAddress; OioSocketChannel( Channel parent, ChannelFactory factory, ChannelPipeline pipeline, ChannelSink sink, Socket socket) { super(parent, factory, pipeline, sink); this.socket = socket; config = new DefaultSocketChannelConfig(socket); } public SocketChannelConfig getConfig() { return config; } public InetSocketAddress getLocalAddress() { InetSocketAddress localAddress = this.localAddress; if (localAddress == null) { try { this.localAddress = localAddress = (InetSocketAddress) socket.getLocalSocketAddress(); } catch (Throwable t) { // Sometimes fails on a closed socket in Windows. return null; } } return localAddress; } public InetSocketAddress getRemoteAddress() { InetSocketAddress remoteAddress = this.remoteAddress; if (remoteAddress == null) { try { this.remoteAddress = remoteAddress = (InetSocketAddress) socket.getRemoteSocketAddress(); } catch (Throwable t) { // Sometimes fails on a closed socket in Windows. return null; } } return remoteAddress; } public boolean isBound() { return isOpen() && socket.isBound(); } public boolean isConnected() { return isOpen() && socket.isConnected(); } @Override protected boolean setClosed() { return super.setClosed(); } @Override protected void setInterestOpsNow(int interestOps) { super.setInterestOpsNow(interestOps); } abstract PushbackInputStream getInputStream(); abstract OutputStream getOutputStream(); @Override public ChannelFuture write(Object message, SocketAddress remoteAddress) { if (remoteAddress == null || remoteAddress.equals(getRemoteAddress())) { return super.write(message, null); } else { return getUnsupportedOperationFuture(); } } }