Package org.jboss.netty.channel.xnio

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

/*
* Copyright 2009 Red Hat, Inc.
*
* Red Hat 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 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: 1685 $, $Date: 2009-08-28 16:15:49 +0900 (금, 28 8 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$FutureConnectionNotifier

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.