FIFO signaling producer that consumer has drained all bytes in pipe

Alan Bateman Alan.Bateman at oracle.com
Sun Aug 30 14:33:12 UTC 2020


On 29/08/2020 00:50, Jason Mehrens wrote:
> Hello nio-dev,
>
> Working on a program where a Java NIO producer of bytes is sending data through a FIFO (created with 'mkfifo' command) to an external process which is the consumer.
> The producer needs a signal that the consumer has completed consuming the bytes so it can be determined that the FIFO can be deleted by the producer.  I've included test case below to demonstrate the concept using cat as the consumer.  So far I think the test demonstrates viability but it has raised a few questions and it would be awesome to get some insights.
>
> 1. FileInputStream::available is the only method that seems to determine the number of bytes in the FIFO.  Is opening with SYNC redundant or necessary to ensure all parties communicate state correctly?
> 2. FileChannel::size always returns zero.  It would be much nicer if FileChannel::size returned bytes available.  Seems like returning zero violates SeekableByteChannel  and FileChannel specs.
> 3. RandomAccessFile::length fails with java.io.IOException: Illegal seek.  Spec seems to indicate that length should return length of the file.  Files(Path)::size, File.length and 'ls' all return zero.  The spec doesn't say anything on being able to seek to determine the length.
> 4. Is there any planned JDK support for FIFOs?  Currently, there is no way to create a FIFO from Java without resorting to calling an external process, JNI, etc.
> 5. Any insights on the demo program? What am I missing?
JEP 380 is adding support for Unix domain sockets and maybe that is an 
option for what you are doing. The only support for pipes is the Pipe 
API which where both ends are in the same VM. It's a bit of stretch to 
try to use the FileChannel or the java.io APIs for FIFO special files 
because many of the operations don't make sense for special files. I 
can't make sense of some of your results, e.g. RAF::length uses fstat64, 
not lseek64 but maybe you are on JDK 8? It should be feasible to have 
FileChannel::size return the number of buffered bytes but that would 
likely introduce an inconsistency with tooling that will return its size 
of 0. On your overall "design", have you considered using two FIFOs so 
that the consumer can communicate that is done?

-Alan


More information about the nio-dev mailing list