Package org.jboss.netty.channel.socket.nio

Source Code of org.jboss.netty.channel.socket.nio.NioSocketChannel$WriteBuffer

/*
* JBoss, Home of Professional Open Source
*
* Copyright 2008, 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.socket.nio;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.channels.SocketChannel;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.AbstractChannel;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelSink;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.util.LinkedTransferQueue;

/**
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
*
* @version $Rev: 535 $, $Date: 2008-11-28 15:57:29 +0900 (Fri, 28 Nov 2008) $
*
*/
abstract class NioSocketChannel extends AbstractChannel
                                implements org.jboss.netty.channel.socket.SocketChannel {

    final SocketChannel socket;
    private final NioSocketChannelConfig config;

    final Object interestOpsLock = new Object();
    final Object writeLock = new Object();

    final AtomicBoolean writeTaskInTaskQueue = new AtomicBoolean();
    final Runnable writeTask = new WriteTask();
    final AtomicInteger writeBufferSize = new AtomicInteger();
    final Queue<MessageEvent> writeBuffer = new WriteBuffer();

    /** Previous return value of isWritable() */
    boolean oldWritable;
    /**
     * Set to true if the amount of data in the writeBuffer exceeds
     * the high water mark, as specified in NioSocketChannelConfig.
     */
    boolean exceededHighWaterMark;
    /**
     * true if and only if NioWorker is firing an event which might cause
     * infinite recursion.
     */
    boolean firingEvent;

    MessageEvent currentWriteEvent;
    int currentWriteIndex;

    public NioSocketChannel(
            Channel parent, ChannelFactory factory,
            ChannelPipeline pipeline, ChannelSink sink,
            SocketChannel socket) {
        super(parent, factory, pipeline, sink);

        this.socket = socket;
        config = new DefaultNioSocketChannelConfig(socket.socket());
    }

    abstract NioWorker getWorker();
    abstract void setWorker(NioWorker worker);

    public NioSocketChannelConfig getConfig() {
        return config;
    }

    public InetSocketAddress getLocalAddress() {
        return (InetSocketAddress) socket.socket().getLocalSocketAddress();
    }

    public InetSocketAddress getRemoteAddress() {
        return (InetSocketAddress) socket.socket().getRemoteSocketAddress();
    }

    public boolean isBound() {
        return isOpen() && socket.socket().isBound();
    }

    public boolean isConnected() {
        return isOpen() && socket.socket().isConnected();
    }

    @Override
    public int getInterestOps() {
        if (!isOpen()) {
            return Channel.OP_WRITE;
        }

        int interestOps = getRawInterestOps();
        if (writeBufferSize.get() >= getConfig().getWriteBufferHighWaterMark()) {
            interestOps |= Channel.OP_WRITE;
        } else {
            interestOps &= ~Channel.OP_WRITE;
        }
        return interestOps;
    }

    int getRawInterestOps() {
        return super.getInterestOps();
    }

    void setRawInterestOpsNow(int interestOps) {
        super.setInterestOpsNow(interestOps);
    }

    @Override
    protected boolean setClosed() {
        return super.setClosed();
    }

    @Override
    protected ChannelFuture getSucceededFuture() {
        return super.getSucceededFuture();
    }

    @Override
    public ChannelFuture write(Object message, SocketAddress remoteAddress) {
        if (remoteAddress == null || remoteAddress.equals(getRemoteAddress())) {
            return super.write(message, null);
        } else {
            return getUnsupportedOperationFuture();
        }
    }

    private final class WriteBuffer extends LinkedTransferQueue<MessageEvent> {
        WriteBuffer() {
            super();
        }

        @Override
        public boolean offer(MessageEvent e) {
            boolean success = super.offer(e);
            assert success;
            writeBufferSize.addAndGet(
                    ((ChannelBuffer) e.getMessage()).readableBytes());
            return true;
        }

        @Override
        public MessageEvent poll() {
            MessageEvent e = super.poll();
            if (e != null) {
                int newWriteBufferSize = writeBufferSize.addAndGet(
                        -((ChannelBuffer) e.getMessage()).readableBytes());
                if (newWriteBufferSize == 0 ||
                    newWriteBufferSize < getConfig().getWriteBufferLowWaterMark()) {
                    exceededHighWaterMark = true;
                }
            }
            return e;
        }
    }

    private final class WriteTask implements Runnable {

        WriteTask() {
            super();
        }

        public void run() {
            writeTaskInTaskQueue.set(false);
            NioWorker.write(NioSocketChannel.this, false);
        }
    }
}
TOP

Related Classes of org.jboss.netty.channel.socket.nio.NioSocketChannel$WriteBuffer

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.