Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * JBoss, Home of Professional Open Source.
    * Copyright 2012 Red Hat, Inc., and individual contributors
    * as indicated by the @author tags.
    *
    * 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 org.apache.tomcat.util.net;
  
  import java.io.File;
  import  java.net.StandardSocketOptions;
  import  java.nio.channels.AsynchronousChannelGroup;
  import  java.nio.channels.AsynchronousServerSocketChannel;
  import  java.nio.channels.CompletionHandler;
  import  java.nio.channels.WritePendingException;
  import  java.nio.file.StandardOpenOption;
  
  
NioEndpoint NIO2 endpoint, providing the following services:
  • Socket channel acceptor thread
  • Simple Worker thread pool, with possible use of executors
Created on Dec 13, 2011 at 9:41:53 AM

Author(s):
Nabil Benothman
  
  public class NioEndpoint extends AbstractEndpoint {
  
  	private AsynchronousServerSocketChannel listener;

Handling of accepted sockets.
  
  	protected Handler handler = null;

The event poller
  
  	private EventPoller eventPoller;

  
SSL context.
  
  	protected SSLContext sslContext;

The static file sender.
  
  	protected Sendfile sendfile;

Using an internal executor.
  
      protected boolean internalExecutor = false;

Create a new instance of NioEndpoint
  
  	public NioEndpoint() {
  		super();
 	}

Parameters:
handler
 
 	public void setHandler(Handler handler) {
 		this. = handler;
 	}

Returns:
the handler
 
 	public Handler getHandler() {
 		return ;
 	}

Number of keep-alive channels.

Returns:
the number of connection
 
 	public int getKeepAliveCount() {
 		return this...size();
 	}

Return the amount of threads that are managed by the pool.

Returns:
the amount of threads that are managed by the pool
 
 	public int getCurrentThreadCount() {
 		return ;
 	}

Return the amount of threads currently busy.

Returns:
the amount of threads currently busy
 
 	public int getCurrentThreadsBusy() {
 		return ;
 	}

Getter for sslContext

Returns:
the sslContext
 
 	public SSLContext getSslContext() {
 		return this.;
 	}

Setter for the sslContext

Parameters:
sslContext the sslContext to set
 
 	public void setSslContext(SSLContext sslContext) {
 		this. = sslContext;
 	}
 
 	/*
 	 * (non-Javadoc)
 	 * 
 	 * @see org.apache.tomcat.util.net.AbstractEndpoint#init()
 	 */
 	public void init() throws Exception {
 		if () {
 			return;
 		}
 
 		if (this. < 0) {
 		}
 
 		if (this. < 0) {
 			this. = this.;
 		}
 
 		// Initialize thread count defaults for acceptor
 		if ( <= 0) {
 		}
 
 		// Create the thread factory
 		if (this. == null) {
 		}
 
 		// If the executor is not set, create it with a fixed thread pool
 		if (this. == null) {
 		     = true;
 			this. = Executors.newFixedThreadPool(this.this.);
 		}
 
 		ExecutorService executorService = (ExecutorServicethis.;
 		AsynchronousChannelGroup threadGroup = AsynchronousChannelGroup
 				.withThreadPool(executorService);
 
 		if (this. == null) {
 			this. = NioServerSocketChannelFactory
 		} else {
 		}
 
 		// Initialize the SSL context if the SSL mode is enabled
 		if () {
 			 = factory.getSslContext();
 		}
 
 		// Initialize the channel factory
 
 		if ( == null) {
 		            );
 		}
 
 		 = true;
 	}
 
 	/*
 	 * (non-Javadoc)
 	 * 
 	 * @see org.apache.tomcat.util.net.AbstractEndpoint#start()
 	 */
 	public void start() throws Exception {
 		// Initialize channel if not done before
 		if (!) {
 			init();
 		}
 		if (!) {
 			 = true;
 			 = false;
 
             // Start acceptor threads
 			for (int i = 0; i < i++) {
 				Thread acceptorThread = newThread(new Acceptor(), "Acceptor");
 				acceptorThread.start();
 			}
 
 			// Start sendfile thread
 			if () {
 				this. = new Sendfile();
 				this..init();
 				Thread sendfileThread = newThread(this."SendFile"true);
 				sendfileThread.start();
 			}
 
 			// Starting the event poller
 			this. = new EventPoller(this.);
 			this..init();
 			Thread eventPollerThread = newThread(this."EventPoller"true);
 			eventPollerThread.start();
 		}
 	}
 
 	/*
 	 * (non-Javadoc)
 	 * 
 	 * @see org.apache.tomcat.util.net.AbstractEndpoint#stop()
 	 */
 	public void stop() {
 		if () {
 			 = false;
 		}
 	}
 
 	/*
 	 * (non-Javadoc)
 	 * 
 	 * @see org.apache.tomcat.util.net.AbstractEndpoint#destroy()
 	 */
 	public void destroy() throws Exception {
 		if () {
 			stop();
 		}
 		if ( != null) {
 			try {
 				.close();
 			} catch (IOException e) {
 			} finally {
 				 = null;
 			}
 		}
 
 		// Destroy the send file thread
 		if (this. != null) {
 		}
 
 		// destroy the send file thread
 		if (this. != null) {
 		}
 
 		// Destroy the server socket channel factory
 
 		// Shut down the executor
 		    ((ExecutorServicethis.).shutdown();
 		     = null;
 		     = false;
 		}
 
 		 = false;
 	}

Configure the channel options before being processed
 
 	protected boolean setChannelOptions(NioChannel channel) {
 		// Process the connection
 		try {
 			// Set channel options: timeout, linger, etc
 			if ( > 0) {
 				channel.setOption(StandardSocketOptions.SO_KEEPALIVE, .);
 			}
 			if ( >= 0) {
 				channel.setOption(StandardSocketOptions.SO_LINGER, );
 			}
 			if () {
 				channel.setOption(StandardSocketOptions.TCP_NODELAY, );
 			}
             if ( > 0) {
                 channel.setOption(StandardSocketOptions.SO_RCVBUF, );
             }
             if ( > 0) {
                 channel.setOption(StandardSocketOptions.SO_SNDBUF, );
             }
 
 			// Initialize the channel
 			return true;
 		} catch (Throwable t) {
 		    if (t instanceof SSLHandshakeException) {
 		    } else {
 		    }
 			return false;
 		}
 	}

Add specified channel and associated pool to the poller. The added will be added to a temporary array, and polled first after a maximum amount of time equal to pollTime (in most cases, latency will be much lower, however). Note: If both read and write are false, the socket will only be checked for timeout; if the socket was already present in the poller, a callback event will be generated and the socket will be removed from the poller.

Parameters:
channel the channel to add to the poller
timeout to use for this connection
read to do read polling
write to do write polling
resume to send a callback event
wakeup
See also:
addEventChannel(NioChannel, long, int)
 
 	public void addEventChannel(NioChannel channellong timeoutboolean readboolean write,
 			boolean resumeboolean wakeup) {
 
 		int flags = (read ? . : 0) | (write ? . : 0)
 				| (resume ? . : 0) | (wakeup ? . : 0);
 
 		addEventChannel(channeltimeoutflags);
 	}

Same as addEventChannel(NioChannel, long, boolean, boolean, boolean, boolean)

Parameters:
channel the channel to add to the poller
timeout the channel timeout
flags a merge of read, write, resume and wake up event types
See also:
addEventChannel(NioChannel, long, boolean, boolean, boolean, boolean)
 
 	public void addEventChannel(NioChannel channellong timeoutint flags) {
 
 		long eventTimeout = timeout <= 0 ?  : timeout;
 
 		if (eventTimeout <= 0) {
 			// Always put a timeout in
 			eventTimeout =  > 0 ?  : .;
 		}
 
 		if (!this..add(channeleventTimeoutflags)) {
 			closeChannel(channel);
 		}
 	}

Remove the channel from the list of venet channels

Parameters:
channel
 
 	public void removeEventChannel(NioChannel channel) {
 		this..remove(channel);
 	}

Add a send file data to the queue of static files

Parameters:
data
Returns:
TRUE if the object is added successfully to the list of SendfileData, else FALSE
 
 	public boolean addSendfileData(SendfileData data) {
 		if (this. != null) {
 			return this..add(data);
 		}
 
 		return false;
 	}

Process given channel.
 
 	protected boolean processChannelWithOptions(NioChannel channel) {
 		try {
 		} catch (Throwable t) {
 			// This means we got an OOM or similar creating a thread, or that
 			// the pool and its queue are full
             ..errorProcessingSocket(t);
 			return false;
 		}
 		return true;
 	}

Process given channel for an event.

Parameters:
channel
status
Returns:
true if the processing of the channel finish successfully else false
 
 	public boolean processChannel(NioChannel channelSocketStatus status) {
 		if (channel == null || channel.isClosed()) {
 			return false;
 		}
 		try {
 			this..execute(new ChannelProcessor(channelstatus));
 			return true;
 		} catch (Throwable t) {
 			// This means we got an OOM or similar creating a thread, or that
 			// the pool and its queue are full
             ..errorProcessingSocket(t);
 			return false;
 		}
 	}

Parameters:
channel
Returns:
 
 	private boolean handshake(NioChannel channel) {
 		try {
 			this..execute(new HandshakeHandler(channel));
 			return true;
 		} catch (Throwable t) {
 			// This means we got an OOM or similar creating a thread, or that
 			// the pool and its queue are full
             ..errorProcessingSocket(t);
 			return false;
 		}
 	}

Getter for serverSocketChannelFactory

Returns:
the serverSocketChannelFactory
 
 	}

Setter for the serverSocketChannelFactory

Parameters:
serverSocketChannelFactory the serverSocketChannelFactory to set
 
 			NioServerSocketChannelFactory serverSocketChannelFactory) {
 		this. = serverSocketChannelFactory;
 	}

Close the specified channel and remove it from the list of open connections

Parameters:
channel the channel to be closed
 
 	public void closeChannel(NioChannel channel) {
 		if (channel != null) {
 			try {
 				channel.close();
 			} catch (IOException e) {
 	            ..errorClosingSocket(e);
 			}
 		}
 	}

Returns:
if the send file is supported, peek up a SendfileData from the pool, else null
 
 		return new SendfileData();
 	}

Acceptor

Server socket acceptor thread.

Created on Mar 6, 2012 at 9:13:34 AM

Author(s):
Nabil Benothman
 
 	protected class Acceptor implements Runnable {

The background thread that listens for incoming TCP/IP connections and hands them off to an appropriate processor.
 
 		public void run() {
 
 			// Loop until we receive a shutdown command
 			while () {
 				// Loop if end point is paused
 				while ( && ) {
 					try {
 						Thread.sleep(1000);
 					} catch (InterruptedException e) {
 						// Ignore
 					}
 				}
                 if (!) {
                     break;
                 }
 
 				try {
 					// Accept the next incoming connection from the server
 					// channel
 					boolean ok = false;
 					if (setChannelOptions(channel) && channel.isOpen()) {
 						if (channel.isSecure()) {
 							handshake(channel);
 							ok = true;
 						} else {
 							ok = processChannel(channelnull);
 						}
 					}
 					// If a problem occurs, close the channel right away
 					if (!ok) {
 		                ..errorProcessingChannel();
 						closeChannel(channel);
 					}
 				} catch (Exception exp) {
 					if () {
 					}
 				} catch (Throwable t) {
                     ..errorAcceptingSocket(t);
 				}
 			}
 		}
 	}

HandshakeHandler

Asynchronous handler for the secure channel handshake. Since the handshake for the secure channels may take awhile, if several new connections are received at the same time, the non-blocking handshake aims to avoid connections to be timed out. Note that this does not guarantee that no connection will be timed out, this depends to the socket SO_TIMEOUT in the client side.

Created on May 23, 2012 at 11:48:45 AM

Author(s):
Nabil Benothman
 
 	protected class HandshakeHandler implements Runnable {
 
 		private NioChannel channel;

Create a new instance of HandshakeProcessor

Parameters:
channel
 
 		public HandshakeHandler(NioChannel channel) {
 			this. = channel;
 		}
 
 		/*
 		 * (non-Javadoc)
 		 * 
 		 * @see java.lang.Runnable#run()
 		 */
 		public void run() {
 			try {
 
 				if (!processChannel(null)) {
                     ..errorProcessingChannel();
 				}
 			} catch (Exception exp) {
                 ..errorProcessingChannelDebug(exp);
 			}
 		}
 
 	}

ChannelInfo

Channel list class, used to avoid using a possibly large amount of objects with very little actual use.

Created on Apr 13, 2012 at 11:13:13 AM

Author(s):
Nabil Benothman
 
 	public static class ChannelInfo {
 
 		public static final int READ = 1;
 
 		public static final int WRITE = 2;
 
 		public static final int RESUME = 4;
 
 		public static final int WAKEUP = 8;
 
 		protected NioChannel channel;
 		protected long timeout;
 		protected int flags;

Create a new instance of ChannelInfo
 
 		public ChannelInfo() {
 			this(null, 0, 0);
 		}

Create a new instance of ChannelInfo

Parameters:
channel the channel
timeout the channel timeout. The default time unit is java.util.concurrent.TimeUnit.MILLISECONDS
flags
 
 		public ChannelInfo(NioChannel channellong timeoutint flags) {
 			this. = channel;
 			this. = timeout;
 			this. = flags;
 		}

Create a new instance of ChannelInfo

Parameters:
channel
timeout
unit
flags
 
 		public ChannelInfo(NioChannel channellong timeoutTimeUnit unitint flags) {
 			this(channel..convert(timeoutunit), flags);
 		}

Returns:
the read flag
 
 		public boolean read() {
 			return ( & ) == ;
 		}

Set the read flag. If the parameter is true, the read flag will have the value 1 else 0.

Parameters:
read
 
 		public void read(boolean read) {
 			this. = (read ? (this. | ) : (this. & 0xE));
 		}

Returns:
the write flag
 
 		public boolean write() {
 			return ( & ) == ;
 		}

Set the write flag. If the parameter is true, the write flag will have the value 1 else 0.

Parameters:
write
 
 		public void write(boolean write) {
 			this. = (write ? (this. | ) : (this. & 0xD));
 		}

Returns:
the resume flag
 
 		public boolean resume() {
 			return ( & ) == ;
 		}

Set the resume flag. If the parameter is true, the resume flag will have the value 1 else 0.

Parameters:
resume
 
 		public void resume(boolean resume) {
 			this. = (resume ? (this. | ) : (this. & 0xB));
 		}

Returns:
the wake up flag
 
 		public boolean wakeup() {
 			return ( & ) == ;
 		}

Set the wakeup flag. If the parameter is true, the wakeup flag will have the value 1 else 0.

Parameters:
wakeup
 
 		public void wakeup(boolean wakeup) {
 			this. = (wakeup ? (this. | ) : (this. & 0x7));
 		}

Merge the tow flags

Parameters:
flag1
flag2
Returns:
the result of merging the tow flags
 
 		public static int merge(int flag1int flag2) {
 			return ((flag1 & ) | (flag2 & )) | ((flag1 & ) | (flag2 & ))
 					| ((flag1 & ) | (flag2 & )) | ((flag1 & ) & (flag2 & ));
 		}
 	}

Handler

Bare bones interface used for socket processing. Per thread data is to be stored in the ThreadWithAttributes extra folders, or alternately in thread local fields.

Created on Mar 6, 2012 at 9:13:07 AM

Author(s):
Nabil Benothman
 
 	public interface Handler {
ChannelState Created on Dec 12, 2011 at 9:41:06 AM

Author(s):
Nabil Benothman
 
 		public enum SocketState {
 
 			OPEN,
 
 			CLOSED,
 
 			LONG
 		}

Process the specified org.apache.tomcat.util.net.NioChannel

Parameters:
channel the org.apache.tomcat.util.net.NioChannel
Returns:
a channel state
 
 		public SocketState process(NioChannel channel);

Process the specified org.apache.tomcat.util.net.NioChannel

Parameters:
channel
status
Returns:
a channel state
 
 		public SocketState event(NioChannel channelSocketStatus status);
 
 	}

ChannelWithOptionsProcessor

This class is the equivalent of the Worker, but will simply use in an external Executor thread pool. This will also set the channel options and do the handshake.

Created on Mar 6, 2012 at 9:09:43 AM

Author(s):
Nabil Benothman
 
 	protected class ChannelWithOptionsProcessor extends ChannelProcessor {

Create a new instance of ChannelWithOptionsProcessor

Parameters:
channel
 
 			super(channel);
 		}
 
 		public void run() {
 			boolean ok = true;
 
 			if (!) {
 			} else {
 				// Process the request from this channel
 			}
 
 			if (!ok) {
 				// Close the channel
 			}
 
 			 = null;
 		}
 	}

ChannelProcessor

This class is the equivalent of the Worker, but will simply use in an external Executor thread pool.

Created on Mar 6, 2012 at 9:10:06 AM

Author(s):
Nabil Benothman
 
 	protected class ChannelProcessor implements Runnable {
 
 		protected NioChannel channel;
 		protected SocketStatus status = null;

Create a new instance of ChannelProcessor

Parameters:
channel
 
 		public ChannelProcessor(NioChannel channel) {
 			this. = channel;
 		}

Create a new instance of ChannelProcessor

Parameters:
channel
status
 
 		public ChannelProcessor(NioChannel channelSocketStatus status) {
 			this(channel);
 			this. = status;
 		}
 
 		public void run() {
 			try {
                 Handler.SocketState state = null;
                 if ( == null) {
                     state = .process();
                 } else {
                     synchronized (.getLock()) {
                         state = .event();
                     }
                 }
 
 				if (state == .) {
 				}
 			} catch (Throwable th) {
                 ..errorProcessingChannelWithException(th);
 			}
 		}
 
 	}

EventPoller Created on Mar 26, 2012 at 12:51:53 PM

Author(s):
Nabil Benothman
 
 	public class EventPoller implements Runnable {

Last run of maintain. Maintain will run usually every 5s.
 
 		protected long lastMaintain = System.currentTimeMillis();
 
 		private Object mutex;
 		private int size;

Create a new instance of EventPoller

Parameters:
size
 
 		public EventPoller(int size) {
 			this. = size;
 		}
 
 		/*
 		 * (non-Javadoc)
 		 * 
 		 * @see java.lang.Runnable#run()
 		 */
 		public void run() {
 			while () {
 				// Loop if endpoint is paused
 				while ( && ) {
 					try {
 						Thread.sleep(1000);
 					} catch (InterruptedException e) {
 						// Ignore
 					}
 				}
 
 				while (this..size() < 1 && ) {
 					synchronized (this.) {
 						try {
							this..wait(10000);
catch (InterruptedException e) {
							// NOPE
				while (this..size() > 0 && ) {
					try {
						Thread.sleep(5000);
catch (InterruptedException e) {
						// NOPE
		}

Check timeouts and raise timeout event
		public void maintain() {
			long date = System.currentTimeMillis();
			// Maintain runs at most once every 5s, although it will likely get
			// called more
			if ((date - ) < 5000L) {
				return;
			// Update the last maintain time
			 = date;
			for (ChannelInfo info : this..values()) {
				if (date >= info.timeout) {
					NioChannel ch = info.channel;
					remove(info);
		}

Remove the channel having the specified id

Parameters:
id
		protected boolean remove(long id) {
			return this..remove(id) != null;
		}

Parameters:
channel
Returns:
true if the channel is removed successfully else false
		public boolean remove(NioChannel channel) {
			return channel != null ? remove(channel.getId()) : false;
		}

Parameters:
info
Returns:
true if the channel-info is removed successfully else false
		public boolean remove(ChannelInfo info) {
			return info != null ? remove(info.channel) : false;
		}

Initialize the event poller
		public void init() {
			this. = new Object();
		}

Destroy the event poller
		public void destroy() {
			synchronized (this.) {
		}

Create a completion handler for read.

Returns:
a reference of java.nio.CompletionHandler
		private CompletionHandler<IntegerNioChannelgetCompletionHandler() {
		    CompletionHandler<IntegerNioChannelhandler = new CompletionHandler<IntegerNioChannel>() {
		        @Override
		        public void completed(Integer nBytesNioChannel attach) {
		            if (nBytes < 0) {
		                failed(new ClosedChannelException(), attach);
		            } else {
		                remove(attach);
		                if (!processChannel(attach.)) {
		                    closeChannel(attach);
		                }
		            }
		        }
		        @Override
		        public void failed(Throwable excNioChannel attach) {
		            remove(attach);
		            if (!processChannel(attach.)) {
		                closeChannel(attach);
		            }
		        }
		    };
			return handler;
		}

Add the channel to the list of channels

Parameters:
channel
timeout
flag
Returns:
true if the channel is added successfully else false
		public boolean add(final NioChannel channellong timeoutint flag) {
			if (this..size() > this.) {
				return false;
			if (channel == null) {
			    return false;
			long date = timeout + System.currentTimeMillis();
			ChannelInfo info = this..get(channel.getId());
			if (info == null) {
				info = new ChannelInfo();
				info.channel = channel;
				info.flags = flag;
				this..put(channel.getId(), info);
else {
				info.flags = ChannelInfo.merge(info.flagsflag);
			// Setting the channel timeout
			info.timeout = date;
			final NioChannel ch = channel;
			if (info.resume()) {
				remove(info);
else if (info.write()) {
				remove(info);
            } else if (info.read()) {
                try {
                    // Trying awaiting for read event
                    ch.awaitRead(chgetCompletionHandler());
                } catch (Exception e) {
                    // Ignore
                    ..errorAwaitingRead(e);
                }
else if (info.wakeup()) {
				remove(info);
				// TODO
			// Wake up all waiting threads
			synchronized (this.) {
			return true;
	}

DefaultThreadFactory The default thread factory Created on Mar 6, 2012 at 9:11:20 AM

Author(s):
Nabil Benothman
	protected static class DefaultThreadFactory implements ThreadFactory {
		private static final AtomicInteger poolNumber = new AtomicInteger(1);
		private final ThreadGroup group;
		private final AtomicInteger threadNumber = new AtomicInteger(1);
		private final String namePrefix;
		private final int threadPriority;
                private final AccessControlContext acc;
                private final ClassLoader ccl;

Create a new instance of DefaultThreadFactory

Parameters:
namePrefix
threadPriority
		public DefaultThreadFactory(String namePrefixint threadPriority) {
			 = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
			this. = namePrefix;
			this. = threadPriority;
                    SecurityManager sm = System.getSecurityManager();
                    if (sm != null) {
                        // Calls to getContextClassLoader from this class
                        // never trigger a security check, but we check
                        // whether our callers have this permission anyways.
                        sm.checkPermission(.);
                        // Fail fast
                        sm.checkPermission(new RuntimePermission("setContextClassLoader"));
                    this. = AccessController.getContext();
                    this. = Thread.currentThread().getContextClassLoader();
		}

Create a new instance of DefaultThreadFactory

Parameters:
threadPriority
		public DefaultThreadFactory(int threadPriority) {
			this("pool-" + .getAndIncrement() + "-thread-"threadPriority);
		}

Create and return a new thread
		public Thread newThread(final Runnable r) {
                        return AccessController.doPrivileged(new PrivilegedAction<Thread>() {
                        @Override
                        public Thread run() {
                            Thread thread = new Thread(new Runnable() {
                                @Override
                                public void run() {
                                    Thread.currentThread().setContextClassLoader();
                                    r.run();
                                }
                            },  + .getAndIncrement(), 0);
                            if (thread.isDaemon()) {
				thread.setDaemon(false);
                            }
                            if (thread.getPriority() != ) {
                                thread.setPriority();
                            }
			return thread;
                    }, );
	}

SendfileData class.
	public static class SendfileData {
		// File
		protected String fileName;
		// Range information
		protected long start;
		protected long end;
		// The channel
		protected NioChannel channel;
		// The file channel
		// Position
		protected long pos;
		// KeepAlive flag
		protected boolean keepAlive;

Prepare the SendfileData

Throws:
IOException
Exception
		protected void setup() throws IOException {
			this. = this.;
			if (this. == null || !this..isOpen()) {
				java.nio.file.Path path = new File(this.).toPath();
				this. = java.nio.channels.FileChannel
						.open(path, StandardOpenOption.READ).position(this.);
		}

Getter for fileName

Returns:
the fileName
		public String getFileName() {
			return this.;
		}

Setter for the fileName

Parameters:
fileName the fileName to set
		public void setFileName(String fileName) {
			this. = fileName;
		}

Getter for start

Returns:
the start
		public long getStart() {
			return this.;
		}

Setter for the start

Parameters:
start the start to set
		public void setStart(long start) {
			this. = start;
		}

Getter for end

Returns:
the end
		public long getEnd() {
			return this.;
		}

Setter for the end

Parameters:
end the end to set
		public void setEnd(long end) {
			this. = end;
		}

Getter for channel

Returns:
the channel
		public NioChannel getChannel() {
			return this.;
		}

Setter for the channel

Parameters:
channel the channel to set
		public void setChannel(NioChannel channel) {
			this. = channel;
		}

Getter for pos

Returns:
the pos
		public long getPos() {
			return this.;
		}

Setter for the pos

Parameters:
pos the pos to set
		public void setPos(long pos) {
			this. = pos;
		}

Getter for keepAlive

Returns:
the keepAlive
		public boolean isKeepAlive() {
			return this.;
		}

Setter for the keepAlive

Parameters:
keepAlive the keepAlive to set
		public void setKeepAlive(boolean keepAlive) {
			this. = keepAlive;
	}

Sendfile Created on Mar 7, 2012 at 4:04:59 PM

Author(s):
Nabil Benothman
	public class Sendfile implements Runnable {
		protected int size;
		private Object mutex;

Returns:
the number of send file
		public int getSendfileCount() {
			return this..get();
		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Runnable#run()
		 */
		public void run() {
			while () {
				// Loop if endpoint is paused
				while ( && ) {
					try {
						Thread.sleep(1000);
catch (InterruptedException e) {
						// Ignore
				// Loop while poller is empty
				while (this..get() < 1 &&  && !) {
					try {
						synchronized (this.) {
							this..wait();
catch (InterruptedException e) {
						// Ignore
				if ( && !) {
					try {
						SendfileData data = this.poll();
						if (data != null) {
							sendFile(data);
catch (Throwable th) {
						// Ignore
		}

Initialize the Sendfile
		protected void init() {
		    this. = ;
			this. = new Object();
			this. = new AtomicInteger(0);
		}

Destroy the SendFile
		protected void destroy() {
			synchronized (this.) {
				// To unlock the
				// Unlock threads waiting for this monitor
		}

Parameters:
data
Throws:
Exception
		private void sendFile(final SendfileData datathrows Exception {
			// Configure the send file data
			data.setup();
			final NioChannel channel = data.channel;
			final int BUFFER_SIZE = channel.getOption(StandardSocketOptions.SO_SNDBUF);
			final ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
			int nr = data.fileChannel.read(buffer);
			if (nr >= 0) {
				buffer.flip();
				try {
					channel.write(bufferdatanew CompletionHandler<IntegerSendfileData>() {
						public void completed(Integer nwSendfileData attachment) {
							if (nw < 0) { // Reach the end of stream
								closeChannel(channel);
								closeFile(attachment.fileChannel);
								return;
							attachment.pos += nw;
							if (attachment.pos >= attachment.end) {
								return;
							boolean ok = true;
							if (!buffer.hasRemaining()) {
								// This means that all data in the buffer has
								// been
								// written => Empty the buffer and read again
								buffer.clear();
								try {
									if (attachment.fileChannel.read(buffer) >= 0) {
										buffer.flip();
else {
										// Reach the EOF
										ok = false;
catch (Throwable th) {
									ok = false;
							if (ok) {
								channel.write(bufferattachmentthis);
else {
								closeFile(attachment.fileChannel);
						public void failed(Throwable excSendfileData attachment) {
							// Closing channels
							closeChannel(channel);
							closeFile(data.fileChannel);
						}

Parameters:
closeable
						private void closeFile(java.io.Closeable closeable) {
							try {
								closeable.close();
catch (IOException e) {
								// NOPE
					});
catch (WritePendingException exp) {
					data.fileChannel.close();
					add(data);
		}

Add the sendfile data to the sendfile poller. Note that in most cases, the initial non blocking calls to sendfile will return right away, and will be handled asynchronously inside the kernel. As a result, the poller will never be used.

Parameters:
data containing the reference to the data which should be sent
Returns:
true if all the data has been sent right away, and false otherwise
		public boolean add(SendfileData data) {