Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6219755
Votes 8
Synopsis PipedOutputStream.write() remains blocked after PipedInputStream was closed
Category java:classes_io
Reported Against
Release Fixed mustang(b57), 5.0u18-rev(b05) (Bug ID:2171403) , 5.0u19(b02) (Bug ID:2176463)
State 10-Fix Delivered, Verified, bug
Priority: 2-High
Related Bugs
Submit Date 20-JAN-2005
Description
The following program works fine in 1.3 and 1.4 but does not terminate in Tiger/Mustang:

===
import java.io.*;
 
public class PipeTest {
  public static void main(String args[]) throws Exception {
    Thread t = null;
    try {
      PipedInputStream in = new PipedInputStream();
      final OutputStream out = new PipedOutputStream(in);
 
      t = new Thread("WriterThread") {
        public void run() {
          try {
            System.out.println("Writer started.");
            out.write(new byte[64*1024]);
          } catch( Throwable e ) {
            System.out.println("Writer exception:");
            e.printStackTrace();
          } finally {
            System.out.println("Writer done.");
          }
        }
      };
      t.start();
      System.out.println("Reader reading...");
      in.read(new byte[2048]);
      System.out.println("Reader closing stream...");
      in.close();
      System.out.println("Reader sleeping 3 seconds...");
      Thread.sleep(3000);
    } catch( Throwable e ) {
      System.out.println("Reader exception:");
      e.printStackTrace();
    } finally {
      System.out.println("Reader done.");
      System.out.println("Active threads:");
      Thread[] threads = new Thread[Thread.activeCount()];
      Thread.enumerate(threads);
      for( int i=0; i<threads.length; i++ ) {
        System.out.println("  " + threads[i]);
      }
      System.out.println("Waiting for writer...");
      t.join();
      System.out.println("Done.");
    }
  }
 
}
===

The expected behavior is that the call to in.close() by the reader awakes the writer (making it throw an "java.io.IOException: Pipe closed"). However, the writer remains blocked forever unless the reader Thread terminates.

The cause would seem to be in PipedInputStream.awaitSpace(), which only checks if the Thread doing the read is alive but not if the Pipe has been closed. That code was modified in Tiger by the fix for 4882082.

  xxxxx@xxxxx   2005-1-20 21:39:52 GMT
Work Around
N/A
Evaluation
This bug got accidentally introduced with the fix to:4882082 that added buffering of
data to the receive(byte b[], int offset, int len) method.

The fix is to enhance the checks made when a writer is waiting for the reader to make some room in the buffer for it to proceed with the further write.
Posted Date : 2005-09-08 06:20:05.0
Comments
  
  Include a link with my name & email   

Submitted On 23-MAY-2006
trejkaz
Can this fix be back-applied to 1.5, since it a regression of functionality from 1.4?


Submitted On 09-JUL-2007
kedu
When will this get fixed in 1.5?


Submitted On 12-APR-2008
volkerk
The following piece of thread dump taken when a JVM was ramping up to using up all resources seems to illustrate this very problem. This really needs a backport to Tiger, it's an ugly bug.

"Thread-67" daemon prio=1 tid=0xdd0b1940 nid=0x9e9 in Object.wait() [0xdec1f000..0xdec1f6f0]
	at java.lang.Object.wait(Native Method)
	at java.io.PipedInputStream.awaitSpace(PipedInputStream.java:204)
	at java.io.PipedInputStream.receive(PipedInputStream.java:161)
	- locked <0x5b222008> (a org.apache.lucene.demo.html.HTMLParser$MyPipedInputStream)
	at java.io.PipedOutputStream.write(PipedOutputStream.java:129)
	at sun.nio.cs.StreamEncoder$CharsetSE.writeBytes(StreamEncoder.java:336)
	at sun.nio.cs.StreamEncoder$CharsetSE.implClose(StreamEncoder.java:427)
	at sun.nio.cs.StreamEncoder.close(StreamEncoder.java:160)
	- locked <0x5b222078> (a java.io.OutputStreamWriter)
	at java.io.OutputStreamWriter.close(OutputStreamWriter.java:222)
	at org.apache.lucene.demo.html.ParserThread.run(ParserThread.java:38)



PLEASE NOTE: JDK6 is formerly known as Project Mustang