JDK-1267045 : java.io.PipedOutputStream.write(b) does not work if reader thread dies
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 1.0.2
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: solaris_2.5
  • CPU: sparc
  • Submitted: 1996-09-09
  • Updated: 2021-11-09
  • Resolved: 1998-03-09
Related Reports
Duplicate :  
Relates :  
Relates :  
Description

Name: saf@russia			Date: 09/09/96


This bug was found by St.Petersburg Java SQE team (by Stanislav Avzan).

The java.io.PipedOutputStream.write() method does not work according to 
the Java language specification when reader thread is no longer alive.

The Java Language specification 
(Version 1.0 - August 1, 1996)
says the following (please see item 22.17.4):

"22.17.4 public void write(int b) throws
IOException 

If a thread was reading data bytes from the connected piped input stream,
but the thread is no longer alive, then an IOException is thrown. 

Implements the write method of OutputStream (p.22.15.1)."

So this method should throw IOException if reader thread is no longer alive.
But in fact it does not.

This bug affects also write(b,off,len) method.
 
Here is the test demonstrating the bug:
    

----- test16.java ---------------------------------------
import java.io.*;

public class test16 {

  public static void main( String[] argv ) {
    PipedOutputStream os = new PipedOutputStream(); 
    PipedInputStream is= new PipedInputStream();
    LazyReader lr;
    int rl;
    try {
      is.connect(os); 
     } catch(Throwable e) {
       System.out.println("Test failed: unexpected <"+e+"> thrown");
       System.exit(1); 
     } 
    byte[] data = new byte[1000];
    lr = new LazyReader(is,"Test",1);// create reader thread with minimal delay
    try {
      os.write(data); //step write 1000 bytes of data
      lr.start();//step start reading bytes of data
      try {
        Thread.sleep(1000); //step sleep for 1 second
      } catch (InterruptedException e1) {}
      if(!(
        is.available() == 0 //step test reader is active
      ))
       { System.out.println("Test failed: no preliminary readings performed" );
         System.exit(1);
       }
    }
    catch(Throwable e) { 
       System.out.println("Test failed: unexpected <"+e+"> thrown");
       System.exit(1);
    }
  //here starts the core of the test
    try {
      lr.stop(); //step stop readerer thread
      System.out.println("Is producer alive? - "+lr.isAlive());
      try {
        Thread.sleep(1000); //step sleep for 1 second
      } catch (InterruptedException e1) {}
      os.write(27); //step try to write into dead thread
      System.out.println("Test failed: no exceptions thrown");
    }
    catch(IOException e) // test IOException is thrown
    { System.out.println("Test passed: IOException thrown");   
    } catch(Throwable e) {
      System.out.println("Test failed: unexpected <"+e+"> thrown"); 
    } 
  }
}
------- LazyReader.java ---------------------------------
import java.io.*;

public class LazyReader extends Thread {
  private PipedInputStream snk;
  private String testid;
  private int delay;

  public LazyReader(PipedInputStream snk, String testid, int delay) {
    this.snk = snk;
    this.testid = testid;
    this.delay = delay;
  }
  
  public void run() {
    try {
      while(true) {
        try {
          Thread.sleep(delay);
        } catch(InterruptedException e) {
        }
        while(snk.available() > 0) snk.read(); //read all written
      }
    } catch(IOException e1) {
        System.out.println(testid + " failed: PipedOutputStream write error");
        System.exit(1);
    }
  }      

}

----- The output of the test: -------------------------

$JAVA test16
Is producer alive? - false
Test failed: no exceptions thrown

-------------------------------------------------------


Workaround:
None
======================================================================

Comments
EVALUATION Possibly a duplicate.
11-06-2004