NBIO: Nonblocking I/O for Java
by Matt Welsh <mdw@cs.berkeley.edu>
10 July 2000

For more information on this package, please see:
  http://www.cs.berkeley.edu/~mdw/proj/java-nbio/
  http://www.cs.berkeley.edu/~mdw/proj/seda/

This library implements nonblocking I/O facilities for Java. Surprisingly,
the standard JDK libraries (as of JDK 1.3) do not provide nonblocking I/O.
This means that in order to implement applications (such as web servers
and other Internet services) which support many concurrent I/O streams,
a large number of threads must be used. However, the overhead of threading
(in Java, as well as more generally) limits the performance of such an
implementation. 

What is needed is a nonblocking I/O library which allows a small number of
threads to be used, along with a select() or poll() like mechanism to 
test for incoming I/O events on a large number of streams. This is what
this library provides.

The public classes included in this library are:

	NonblockingInputStream
	  A subclass of java.io.InputStream which supports nonblocking
	  semantics. 

	NonblockingOutputStream
	  A subclass of java.io.OutputStream which supports nonblocking
	  semantics.

	NonblockingSocket
	  A subclass of java.net.Socket which supports nonblocking semantics.
	  Socket connection and read/write are nonblocking.

	NonblocingServerSocket
	  A variant of java.net.ServerSocket which supports nonblocking 
	  semantics. Connection accept is nonblocking.

	SelectSet
	  A class which implements select(), allowing you to poll for
	  events across a number of nonblocking I/O streams. The interface
	  is in fact very similar to the SVR4 poll() system call.

	SelectItem
	  A class which represents a single nonblocking I/O stream to be
	  used with SelectSet.

In the 'test' directory you will find a number of test programs which
demonstrate the use of this library:

	test/test
	  Blocking and nonblocking variants of a simple server and client
	  application, used for demonstration purposes.

	test/p2p-bench
	  The 'TCPBench' program is a point-to-point TCP benchmark, like
	  'ttcp' for Java. It can use either blocking or nonblocking sockets,
	  and reports both round-trip latency and bandwidth for a given 
	  message size.

	test/multi-bench
	  The 'MultiServer' program is a benchmark which implements a simple
	  TCP server which supports many connections. It is capable of 
	  using either nonblocking sockets (with a single thread) or blocking
	  sockets (with many threads). It exchanges a series of packets 
	  which each client that connects to it. The benchmark reports
	  the total bandwidth measured by the server. The 'MultiClient' 
	  program is used as the client.

This library is for use with NATIVE THREADS ONLY. This is very important.
The issue here is that calling SelectSet.select() actually blocks the
thread making the call. If you are using Green Threads, this will block
the entire JVM. This is fine for a single-threaded application, but in
general you only want to block the thread making the call. Supporting this
behavior under Green Threads is complicated and I don't think it's important;
with the NBIO library you should be able to use native threads, since you
will need much fewer of them than you would with blocking I/O.

Of course, you can use the other NBIO routines (nonblocking sockets, etc.) 
with green threads, since they do not block. SelectSet.select() is the only
real problem.

This library makes use of a native code wrapper to the nonblocking I/O and
poll() system calls, the code for which is found in the 'jni' directory.
This has thus far only been tested on Linux 2.2.x with glibc 2.1.1, but
should be readily portable to other UNIX systems. To use this library you
need to make the file 'jni/libNBIO.so' available on your LD_LIBRARY_PATH,
for example by using the following command:
	export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`/jni

In the future we would like to support nonblocking disk I/O, however, most
UNIX-based operating systems do not in fact support nonblocking access to
disk files; you must use a lower-level "raw disk" facility instead. Eventually
We intend to extend this library to support Linux's raw disk I/O.

If you have any questions, comments, or bug reports, don't hesitate to get
in touch with me!

Matt Welsh <mdw@cs.berkeley.edu>

