You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by "Catherine Hope (JIRA)" <ji...@apache.org> on 2010/01/19 11:28:54 UTC

[jira] Created: (HARMONY-6431) BufferedReader.read() doesn't throw an IOException when an underlying socket is closed

BufferedReader.read() doesn't throw an IOException when an underlying socket is closed
--------------------------------------------------------------------------------------

                 Key: HARMONY-6431
                 URL: https://issues.apache.org/jira/browse/HARMONY-6431
             Project: Harmony
          Issue Type: Bug
          Components: Classlib
    Affects Versions: 5.0M12
         Environment: linux
            Reporter: Catherine Hope


Calling BufferedReader.read() on a socket input stream will block indefinitely if the socket is closed after the read has been called.  In this situation the RI behaviour is to throw a java.net.SocketException (subclass of IOException).  

The problem causes the Eclipse junit runner org.eclipse.jdt.internal.junit.runner.RemoteTestRunner to hang on termination, as it's using a socket.close() to cause a reader thread to shutdown.

The problem can be recreated by opening a socket, creating a BufferedReader from the socket input stream, performing a read in another thread and then closing the socket.  The problem is caused by the native code doing a blocking read using the system call recv.  I can fix the problem easily using the selectRead call which (on linux) using poll to wait on data being available or an exception occurring before calling recv.  A better performance solution would be to use the close() to send a signal to any blocked reads on the socket, which is what the RI does.

This issue has been discussed previously on a deleted JIRA so I'm raising this one to flag as a known problem.

Testcase (don't add as it hangs):

	/**
     * @tests java.io.BufferedReader#read() when the underlying socket is closed
     * during the read
     */
	public void test_read_closed_socket() throws IOException, InterruptedException {
	    ServerSocket ss = new ServerSocket(0);
        Socket socket = new Socket("", ss.getLocalPort());
        br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        Thread rt = new Thread(){
            public void run() {
                try {
                    br.read();
                } catch (IOException e) {
                    // expected behaviour
                }
            }
        };
        rt.start();
        // sleep isn't essential but increases likelihood of hang
        Thread.sleep(100);
        socket.close();
        br.close();
        rt.join();
    }

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Re: [jira] Commented: (HARMONY-6431) BufferedReader.read() doesn't throw an IOException when an underlying socket is closed

Posted by Catherine Hope <ca...@googlemail.com>.
It's the same problem in terms of a blocked read isn't being interrupted by
the close, but in different classes and the read operation is on a socket.
The deadlock I got in the eclipse runner is in this thread situation:

Thread=main (08940B88) Status=Blocked on flat lock
Monitor=08B8C5A8 (Object monitor for java/io/InputStreamReader @ 979BDB40)
Count=1
Owner=ReaderThread(08B55600)
    at java/io/BufferedReader.close()V (BufferedReader.java:116)
    at org/eclipse/jdt/internal/junit/runner/RemoteTestRunner.shutDown()V
(RemoteTestRunner.java:602)
    at org/eclipse/jdt/internal/junit/runner/RemoteTestRunner.run()V
(RemoteTestRunner.java:390)
    at
org/eclipse/jdt/internal/junit/runner/RemoteTestRunner.main([Ljava/lang/String;)V
(RemoteTestRunner.java:196)

Thread=ReaderThread (08B60F04) Status=Running
    at
org/apache/harmony/luni/platform/OSNetworkSystem.read(Ljava/io/FileDescriptor;[BIII)I
(Native Method)
    at org/apache/harmony/luni/net/PlainSocketImpl.read([BII)I
(PlainSocketImpl.java:556)
    at org/apache/harmony/luni/net/SocketInputStream.read([BII)I
(SocketInputStream.java:88)
    at java/io/InputStreamReader.read([CII)I (InputStreamReader.java:261)
    at java/io/BufferedReader.fillBuf()I (BufferedReader.java:135)
    at java/io/BufferedReader.readLine()Ljava/lang/String;
(BufferedReader.java:366)
    at
org/eclipse/jdt/internal/junit/runner/RemoteTestRunner$ReaderThread.run()V
(RemoteTestRunner.java:140)

On Wed, Jan 20, 2010 at 5:11 AM, Regis Xu (JIRA) <ji...@apache.org> wrote:

>
>    [
> https://issues.apache.org/jira/browse/HARMONY-6431?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12802673#action_12802673]
>
> Regis Xu commented on HARMONY-6431:
> -----------------------------------
>
> It seems duplicate of HARMONY-6014. Some patches try to fix it, but not yet
> completely fixed.
>
> > BufferedReader.read() doesn't throw an IOException when an underlying
> socket is closed
> >
> --------------------------------------------------------------------------------------
> >
> >                 Key: HARMONY-6431
> >                 URL: https://issues.apache.org/jira/browse/HARMONY-6431
> >             Project: Harmony
> >          Issue Type: Bug
> >          Components: Classlib
> >    Affects Versions: 5.0M12
> >         Environment: linux
> >            Reporter: Catherine Hope
> >
> > Calling BufferedReader.read() on a socket input stream will block
> indefinitely if the socket is closed after the read has been called.  In
> this situation the RI behaviour is to throw a java.net.SocketException
> (subclass of IOException).
> > The problem causes the Eclipse junit runner
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner to hang on
> termination, as it's using a socket.close() to cause a reader thread to
> shutdown.
> > The problem can be recreated by opening a socket, creating a
> BufferedReader from the socket input stream, performing a read in another
> thread and then closing the socket.  The problem is caused by the native
> code doing a blocking read using the system call recv.  I can fix the
> problem easily using the selectRead call which (on linux) using poll to wait
> on data being available or an exception occurring before calling recv.  A
> better performance solution would be to use the close() to send a signal to
> any blocked reads on the socket, which is what the RI does.
> > This issue has been discussed previously on a deleted JIRA so I'm raising
> this one to flag as a known problem.
> > Testcase (don't add as it hangs):
> >       /**
> >      * @tests java.io.BufferedReader#read() when the underlying socket is
> closed
> >      * during the read
> >      */
> >       public void test_read_closed_socket() throws IOException,
> InterruptedException {
> >           ServerSocket ss = new ServerSocket(0);
> >         Socket socket = new Socket("", ss.getLocalPort());
> >         br = new BufferedReader(new
> InputStreamReader(socket.getInputStream()));
> >         Thread rt = new Thread(){
> >             public void run() {
> >                 try {
> >                     br.read();
> >                 } catch (IOException e) {
> >                     // expected behaviour
> >                 }
> >             }
> >         };
> >         rt.start();
> >         // sleep isn't essential but increases likelihood of hang
> >         Thread.sleep(100);
> >         socket.close();
> >         br.close();
> >         rt.join();
> >     }
>
> --
> This message is automatically generated by JIRA.
> -
> You can reply to this email to add a comment to the issue online.
>
>


-- 
Catherine Hope
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number
741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire
PO6 3AU

[jira] Commented: (HARMONY-6431) BufferedReader.read() doesn't throw an IOException when an underlying socket is closed

Posted by "Regis Xu (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HARMONY-6431?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12802673#action_12802673 ] 

Regis Xu commented on HARMONY-6431:
-----------------------------------

It seems duplicate of HARMONY-6014. Some patches try to fix it, but not yet completely fixed.

> BufferedReader.read() doesn't throw an IOException when an underlying socket is closed
> --------------------------------------------------------------------------------------
>
>                 Key: HARMONY-6431
>                 URL: https://issues.apache.org/jira/browse/HARMONY-6431
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>    Affects Versions: 5.0M12
>         Environment: linux
>            Reporter: Catherine Hope
>
> Calling BufferedReader.read() on a socket input stream will block indefinitely if the socket is closed after the read has been called.  In this situation the RI behaviour is to throw a java.net.SocketException (subclass of IOException).  
> The problem causes the Eclipse junit runner org.eclipse.jdt.internal.junit.runner.RemoteTestRunner to hang on termination, as it's using a socket.close() to cause a reader thread to shutdown.
> The problem can be recreated by opening a socket, creating a BufferedReader from the socket input stream, performing a read in another thread and then closing the socket.  The problem is caused by the native code doing a blocking read using the system call recv.  I can fix the problem easily using the selectRead call which (on linux) using poll to wait on data being available or an exception occurring before calling recv.  A better performance solution would be to use the close() to send a signal to any blocked reads on the socket, which is what the RI does.
> This issue has been discussed previously on a deleted JIRA so I'm raising this one to flag as a known problem.
> Testcase (don't add as it hangs):
> 	/**
>      * @tests java.io.BufferedReader#read() when the underlying socket is closed
>      * during the read
>      */
> 	public void test_read_closed_socket() throws IOException, InterruptedException {
> 	    ServerSocket ss = new ServerSocket(0);
>         Socket socket = new Socket("", ss.getLocalPort());
>         br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
>         Thread rt = new Thread(){
>             public void run() {
>                 try {
>                     br.read();
>                 } catch (IOException e) {
>                     // expected behaviour
>                 }
>             }
>         };
>         rt.start();
>         // sleep isn't essential but increases likelihood of hang
>         Thread.sleep(100);
>         socket.close();
>         br.close();
>         rt.join();
>     }

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.