Package org.jboss.netty.channel.xnio

Source Code of org.jboss.netty.channel.xnio.XnioClientChannelSink

/*
* JBoss, Home of Professional Open Source
*
* Copyright 2009, Red Hat Middleware LLC, and individual contributors
* by the @author tags. See the COPYRIGHT.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.netty.channel.xnio;

import static org.jboss.netty.channel.Channels.*;

import java.nio.channels.AlreadyConnectedException;
import java.nio.channels.ConnectionPendingException;
import java.nio.channels.GatheringByteChannel;

import org.jboss.netty.channel.AbstractChannelSink;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelState;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.xnio.FutureConnection;
import org.jboss.xnio.IoFuture;
import org.jboss.xnio.IoFuture.Notifier;
import org.jboss.xnio.channels.MultipointWritableMessageChannel;
import org.jboss.xnio.channels.SuspendableReadChannel;
import org.jboss.xnio.channels.SuspendableWriteChannel;
import org.jboss.xnio.channels.WritableMessageChannel;

/**
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
* @version $Rev: 1070 $, $Date: 2009-03-16 14:00:29 +0900 (Mon, 16 Mar 2009) $
*/
final class XnioClientChannelSink extends AbstractChannelSink {

    private static final XnioClientChannelHandler HANDLER = new XnioClientChannelHandler();

    XnioClientChannelSink() {
        super();
    }

    @SuppressWarnings("unchecked")
    public void eventSunk(
            ChannelPipeline pipeline, ChannelEvent e) throws Exception {
        BaseXnioChannel channel = (BaseXnioChannel) e.getChannel();
        if (e instanceof ChannelStateEvent) {
            ChannelStateEvent event = (ChannelStateEvent) e;
            ChannelFuture future = event.getFuture();
            ChannelState state = event.getState();
            Object value = event.getValue();

            switch (state) {
            case OPEN:
                if (Boolean.FALSE.equals(value)) {
                    channel.closeNow(future);
                }
                break;
            case BOUND:
            case CONNECTED:
                if (value != null) {
                    if (channel instanceof XnioClientChannel) {
                        final XnioClientChannel cc = (XnioClientChannel) channel;
                        synchronized (cc.connectLock) {
                            if (cc.connecting) {
                                Exception cause = new ConnectionPendingException();
                                future.setFailure(cause);
                                fireExceptionCaught(channel, cause);
                            } else {
                                cc.connecting = true;
                                java.nio.channels.Channel xnioChannel = cc.xnioChannel;
                                if (xnioChannel == null) {
                                    FutureConnection fc =
                                        cc.xnioConnector.connectTo(value, HANDLER);
                                    fc.addNotifier(new FutureConnectionNotifier(cc), future);
                                } else {
                                    Exception cause = new AlreadyConnectedException();
                                    future.setFailure(cause);
                                    fireExceptionCaught(cc, cause);
                                }
                            }
                        }
                    } else {
                        Exception cause = new UnsupportedOperationException();
                        future.setFailure(cause);
                        fireExceptionCaught(channel, cause);
                    }
                } else {
                    channel.closeNow(future);
                }
                break;
            case INTEREST_OPS:
                int interestOps = ((Integer) value).intValue();
                java.nio.channels.Channel xnioChannel = channel.xnioChannel;
                if (xnioChannel instanceof SuspendableReadChannel) {
                    if ((interestOps & Channel.OP_READ) == 0) {
                        ((SuspendableReadChannel) xnioChannel).suspendReads();
                        channel.setRawInterestOpsNow(Channel.OP_NONE);
                    } else {
                        ((SuspendableReadChannel) xnioChannel).resumeReads();
                        channel.setRawInterestOpsNow(Channel.OP_READ);
                    }
                }
                e.getFuture().setSuccess();
                break;
            }
        } else if (e instanceof MessageEvent) {
            MessageEvent event = (MessageEvent) e;
            java.nio.channels.Channel xnioChannel = channel.xnioChannel;
            if (xnioChannel instanceof GatheringByteChannel ||
                xnioChannel instanceof MultipointWritableMessageChannel ||
                xnioChannel instanceof WritableMessageChannel) {
                boolean offered = channel.writeBuffer.offer(event);
                assert offered;
                if (xnioChannel instanceof SuspendableWriteChannel) {
                    ((SuspendableWriteChannel) xnioChannel).resumeWrites();
                }
            } else {
                event.getFuture().setFailure(new IllegalStateException());
            }
        }
    }

    @SuppressWarnings("unchecked")
    private static final class FutureConnectionNotifier implements Notifier {

        private final XnioClientChannel cc;

        FutureConnectionNotifier(XnioClientChannel cc) {
            this.cc = cc;
        }

        public void notify(IoFuture future, Object attachment) {
            ChannelFuture cf = (ChannelFuture) attachment;
            try {
                java.nio.channels.Channel xnioChannel = (java.nio.channels.Channel) future.get();
                cc.xnioChannel = xnioChannel;
                XnioChannelRegistry.registerChannelMapping(cc);
                cf.setSuccess();
            } catch (Throwable t) {
                cf.setFailure(t);
                fireExceptionCaught(cc, t);
            } finally {
                cc.connecting = false;
            }
        }
    }
}
TOP

Related Classes of org.jboss.netty.channel.xnio.XnioClientChannelSink

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.