Our discussion on thread overheads and using nonblocking I/O in Java
strikes close to home - here at Berkeley we are building an event-driven
Internet server platform, implemented entirely in Java. Obviously for this
to work we need nonblocking I/O primitives.
So, I've been working on implementing a simple nonblocking socket class
in Java which lets you do nonblocking read/write/connect/accept as well
as select(). It's conceptually very simple, and apart from the select()
call looks just like a regular Java Socket.
Turns out this is not as easy as it could be -- because even though you call
system calls like read(), write(), and fcntl() from native code, these are
trapped by the Java runtime library to do magic things when green threads
are used!
In other words, although I was creating a nonblocking socket and issuing
read calls against it in JNI-based C code, those system calls (from C)
were in fact being caught by the Java runtime library which was turning
them back into "blocking" access to the socket. This is because the green
threads library is very aggressive about preventing native code from stalling
the whole application by issuing a blocking system call - it in fact turns
all blocking system calls into nonblocking calls, and issues (green thread)
context switches when a block would occur.
The solution? Go behind JNI's back, and get the "real" system call handles
by using dlopen/dlsym on /lib/libc.so.6 (or wherever your standard C library
happens to be installed), and call them directly.
The good news is that it seems to work. Note that when native threads are used,
the JDK does not attempt any funny business, and there are no problems.
Matt Welsh, UC Berkeley
----------------------------------------------------------------------
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]