All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.craft.atom.nio.NioByteChannel Maven / Gradle / Ivy

There is a newer version: 3.1.2
Show newest version
package io.craft.atom.nio;

import io.craft.atom.io.AbstractIoByteChannel;
import io.craft.atom.io.ChannelEvent;
import io.craft.atom.io.ChannelState;
import io.craft.atom.io.IllegalChannelStateException;
import io.craft.atom.nio.spi.NioBufferSizePredictor;
import io.craft.atom.nio.spi.NioChannelEventDispatcher;

import java.io.IOException;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicBoolean;

import lombok.ToString;


/**
 * Channel transmit bytes base nio
 * 
 * @author mindwind
 * @version 1.0, Feb 21, 2013
 * @see NioTcpByteChannel
 * @see NioUdpByteChannel
 */
@ToString(callSuper = true, of = { "localAddress", "remoteAddress" })
abstract public class NioByteChannel extends AbstractIoByteChannel {
	                   
	
	protected          SocketAddress               localAddress                                                        ;
	protected          SocketAddress               remoteAddress                                                       ;
	protected          SelectionKey                selectionKey                                                        ;
	protected          NioProcessor                processor                                                           ;
	protected final    Semaphore                   semaphore                                                           ;
	protected final    NioChannelEventDispatcher   dispatcher                                                          ;
	protected final    NioBufferSizePredictor      predictor                                                           ;
	protected final    Queue           writeBufferQueue = new ConcurrentLinkedQueue()          ;
	protected final    Queue> eventQueue       = new ConcurrentLinkedQueue>();
	protected final    Object                      lock             = new Object()                                     ;
	protected final    AtomicBoolean               scheduleFlush    = new AtomicBoolean(false)                         ;
	protected volatile boolean                     eventProcessing  = false                                            ;
	
	
	// ~ ------------------------------------------------------------------------------------------------------------

	
	public NioByteChannel(NioConfig config, NioBufferSizePredictor predictor, NioChannelEventDispatcher dispatcher) {
		super(config.getMinReadBufferSize(), config.getDefaultReadBufferSize(), config.getMaxReadBufferSize());
		this.semaphore = new Semaphore(config.getChannelEventSize(), false);
		this.predictor = predictor;
		this.dispatcher = dispatcher;
	}
	
	
	// ~ ------------------------------------------------------------------------------------------------------------

	
	@Override
	public void close() {
		synchronized (lock) {
            if (isClosing() || isClosed()) {
                return;
            }
        }
		
		processor.remove(this);
	}

	@Override
	public boolean write(byte[] data) throws IllegalChannelStateException {
		if (isClosed())   { throw new IllegalChannelStateException("Channel is closed"); }
		if (isClosing())  { throw new IllegalChannelStateException("Channel is closing"); }
		if (isPaused())   { throw new IllegalChannelStateException("Channel is paused"); }
		if (data == null) { return false; }
		
		setLastIoTime(System.currentTimeMillis());
		getWriteBufferQueue().add(ByteBuffer.wrap(data));
		processor.flush(this);
		return true;
	}
	
	@Override
	public Queue getWriteQueue() {
		Queue q = new LinkedBlockingQueue();
		for (ByteBuffer buf : writeBufferQueue) {
			q.add(buf.array());
		}
		return q;
	}
	
	@Override
	public SocketAddress getLocalAddress() {
		return localAddress;
	}
	
	@Override
	public SocketAddress getRemoteAddress() {
		return remoteAddress;
	}
	
	public void setProcessor(NioProcessor processor) {
		this.processor = processor;
	}
	
	public boolean tryAcquire() {
		return semaphore.tryAcquire();
	}
	
	public void release() {
		semaphore.release();
	}
	
	public int availablePermits() {
		return semaphore.availablePermits();
	}
	
    public void unsetScheduleFlush() {
    	scheduleFlush.set(false);
    }
    
    public boolean setScheduleFlush(boolean schedule) {
        if (schedule) {
            return scheduleFlush.compareAndSet(false, schedule);
        }

        scheduleFlush.set(schedule);
        return true;
    }
	
    
	// ~ ------------------------------------------------------------------------------------------------------------
	
    
	void add(ChannelEvent event) {
		eventQueue.offer(event);
	}
	
	boolean isValid() {		
		if (isClosing()) {
			return false;
		}
		
		if (isClosed()) {
			return false;
		}
		
		return true;
	}
	
	void setClosing() {
		this.state = ChannelState.CLOSING;
	}
	
	void setClosed() {
		this.state = ChannelState.CLOSED;
	}
	
	void setRemoteAddress(SocketAddress remoteAddress) {
		this.remoteAddress = remoteAddress;
	}
	
	SelectionKey getSelectionKey() {
		return selectionKey;
	}
	
	void setSelectionKey(SelectionKey key) {
		this.selectionKey = key;
	}
	
	Queue getWriteBufferQueue() {
		return writeBufferQueue;
	}
	
	Queue> getEventQueue() {
		return eventQueue;
	}
	
	boolean isEventProcessing() {
		return eventProcessing;
	}
	
	void setEventProcessing(boolean eventProcessing) {
		this.eventProcessing = eventProcessing;
	}
	
	boolean isReadable() {
		return isOpen() && selectionKey.isValid() && selectionKey.isReadable();
	}
	
	boolean isWritable() {
		return (isOpen() || isPaused()) && selectionKey.isValid() && selectionKey.isWritable();
	}
	
	NioBufferSizePredictor getPredictor() {
		return predictor;
	}

	
	// ~ ------------------------------------------------------------------------------------------------------------

	
	protected void close0() throws IOException { /* override this */ }
	protected int readTcp(ByteBuffer buf) throws IOException { return 0; /* override this */ }
	protected int writeTcp(ByteBuffer buf) throws IOException { return 0; /* override this */ }
	protected int writeUdp(ByteBuffer buf, SocketAddress target) throws IOException { return 0; /* override */ }
	protected SocketAddress readUdp(ByteBuffer buf) throws IOException { return null; /* override this */ }
	abstract protected SelectableChannel innerChannel();
	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy