While working on AIOJ, I came across an issue with java.lang.Object.wait() and and calling java.lang.Object.notify() from a signal handler.

With POSIX AIO, there are two ways to receive notification that an I/O operation has completed. One is through a signal and the other is by calling a specified method in a temporary thread. When using signal notification, the signal is received by the thread that initiated the AIO operation.

Consider the following code snippet:

  AioFuture future = aioChannel.read(buffer, 0L);
  future.get();

If aioChannel is an instance of PosixAsynchronousFileChannel, calling read invokes a native method that calls aio_read and return an AioFuture object that represents the asynchronous operation. Calling AioFuture.get() tells the current thread to block until the asynchronous operation has completed and return the number of bytes that were read.

The problem comes when we’ve configured the instance of aioChannel to use signal notifications. It seams straight forward to call java.lang.Object.wait() in the implementation of AioFuture.get(). When the signal notifies us that the asynchronous I/O operation has completed, calling java.lang.Object.notifyAll() should notify any waiting threads that they can continue. What happens in this case is that java.lang.Object.wait() gets called and while it blocks, the I/O completion gets sent to the thread. The signal handler gets called by the waiting thread. java.lang.Object.notifyAll() is called by the signal handler. When the signal handler returns, the thread is still waiting. I’m not 100% certain why this is happening but I assume it something to do with the thread not expecting to receive a notify from itself.

I have only found one workaround for this problem and that is to use a spin-lock. Unfortunately, this is less desirable because a spin-lock consumes so much CPU time. I tried calling java.lang.Object.notifyAll() from a second thread without success. It appears that once the signal handler has been called, the thread can no longer be notified. I will dig deeper into this problem and post the results here.