You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by "Kevin Zhou (JIRA)" <ji...@apache.org> on 2008/11/12 04:19:44 UTC

[jira] Created: (HARMONY-6014) [classlib][luni] BufferedInputStream can not be closed in another thread

[classlib][luni] BufferedInputStream can not be closed in another thread
------------------------------------------------------------------------

                 Key: HARMONY-6014
                 URL: https://issues.apache.org/jira/browse/HARMONY-6014
             Project: Harmony
          Issue Type: Bug
          Components: Classlib
    Affects Versions: 5.0M7
            Reporter: Kevin Zhou
             Fix For: 5.0M8


Give the following test scenario [1], it start BufferedInputStream object in the main thread, and try to close it in another thread.
HARMONY fails to close it since the main thread can still read bytes from the buffer.

[1] 
public void test_BufferedInputStream_close() {
        InputStream inputStream = new InputStream() {
            Object lock = new Object();
            public int read() {
                return 1;
            }
            public int read(byte[] buf, int offset, int length) {
                synchronized (lock) {
                    try {
                        lock.wait(3000);
                    } catch (InterruptedException e) {
                        // Ignore
                    }
                }
                return 1;
            }
            public void close() {
                synchronized (lock) {
                    lock.notifyAll();
                }
            }
        };
        final BufferedInputStream buffer = new BufferedInputStream(inputStream);
        Runnable runnable = new Runnable() {
            public void run() {
                try {
                    Thread.sleep(1000);
                    buffer.close();
                } catch (Exception e) {
                    // Ignored
                }
            }
        };
        new Thread(runnable).start();
        try {
            buffer.read(new byte[100], 0, 99);
            fail("Should throw IOException");
        } catch (IOException e) {
            // Expected
        }
    }

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


[jira] Updated: (HARMONY-6014) [classlib][luni] BufferedInputStream can not be closed in another thread

Posted by "Regis Xu (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HARMONY-6014?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Regis Xu updated HARMONY-6014:
------------------------------

    Attachment: hy-6014.regis.diff

this patch revert commit r721075 firstly, and then use the same way of archiving asynchronous close in HARMONY-6073

after the patch, BufferedInputStream.close() could be invoked asynchronous, but the behavior of after closing a stream blocking at read() has a little differnce with RI, which throws throw IOException: Stream closed, while Harmony just return what read from wrapped stream silently.

> [classlib][luni] BufferedInputStream can not be closed in another thread
> ------------------------------------------------------------------------
>
>                 Key: HARMONY-6014
>                 URL: https://issues.apache.org/jira/browse/HARMONY-6014
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>    Affects Versions: 5.0M7
>            Reporter: Kevin Zhou
>            Assignee: Tim Ellison
>             Fix For: 5.0M8
>
>         Attachments: HARMONY-6014.diff, hy-6014.regis.diff, stream.patch
>
>   Original Estimate: 24h
>  Remaining Estimate: 24h
>
> Give the following test scenario [1], it start BufferedInputStream object in the main thread, and try to close it in another thread.
> HARMONY fails to close it since the main thread can still read bytes from the buffer.
> [1] 
> public void test_BufferedInputStream_close() {
>         InputStream inputStream = new InputStream() {
>             Object lock = new Object();
>             public int read() {
>                 return 1;
>             }
>             public int read(byte[] buf, int offset, int length) {
>                 synchronized (lock) {
>                     try {
>                         lock.wait(3000);
>                     } catch (InterruptedException e) {
>                         // Ignore
>                     }
>                 }
>                 return 1;
>             }
>             public void close() {
>                 synchronized (lock) {
>                     lock.notifyAll();
>                 }
>             }
>         };
>         final BufferedInputStream buffer = new BufferedInputStream(inputStream);
>         Runnable runnable = new Runnable() {
>             public void run() {
>                 try {
>                     Thread.sleep(1000);
>                     buffer.close();
>                 } catch (Exception e) {
>                     // Ignored
>                 }
>             }
>         };
>         new Thread(runnable).start();
>         try {
>             buffer.read(new byte[100], 0, 99);
>             fail("Should throw IOException");
>         } catch (IOException e) {
>             // Expected
>         }
>     }

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


[jira] Resolved: (HARMONY-6014) [classlib][luni] BufferedInputStream can not be closed in another thread

Posted by "Sean Qiu (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HARMONY-6014?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Sean Qiu resolved HARMONY-6014.
-------------------------------

    Resolution: Fixed

But it works :-)

Applied at r721075, please verify if it works as expected.

> [classlib][luni] BufferedInputStream can not be closed in another thread
> ------------------------------------------------------------------------
>
>                 Key: HARMONY-6014
>                 URL: https://issues.apache.org/jira/browse/HARMONY-6014
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>    Affects Versions: 5.0M7
>            Reporter: Kevin Zhou
>            Assignee: Sean Qiu
>             Fix For: 5.0M8
>
>         Attachments: HARMONY-6014.diff, stream.patch
>
>   Original Estimate: 24h
>  Remaining Estimate: 24h
>
> Give the following test scenario [1], it start BufferedInputStream object in the main thread, and try to close it in another thread.
> HARMONY fails to close it since the main thread can still read bytes from the buffer.
> [1] 
> public void test_BufferedInputStream_close() {
>         InputStream inputStream = new InputStream() {
>             Object lock = new Object();
>             public int read() {
>                 return 1;
>             }
>             public int read(byte[] buf, int offset, int length) {
>                 synchronized (lock) {
>                     try {
>                         lock.wait(3000);
>                     } catch (InterruptedException e) {
>                         // Ignore
>                     }
>                 }
>                 return 1;
>             }
>             public void close() {
>                 synchronized (lock) {
>                     lock.notifyAll();
>                 }
>             }
>         };
>         final BufferedInputStream buffer = new BufferedInputStream(inputStream);
>         Runnable runnable = new Runnable() {
>             public void run() {
>                 try {
>                     Thread.sleep(1000);
>                     buffer.close();
>                 } catch (Exception e) {
>                     // Ignored
>                 }
>             }
>         };
>         new Thread(runnable).start();
>         try {
>             buffer.read(new byte[100], 0, 99);
>             fail("Should throw IOException");
>         } catch (IOException e) {
>             // Expected
>         }
>     }

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


[jira] Commented: (HARMONY-6014) [classlib][luni] BufferedInputStream can not be closed in another thread

Posted by "Kevin Zhou (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HARMONY-6014?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12647227#action_12647227 ] 

Kevin Zhou commented on HARMONY-6014:
-------------------------------------

We have conducted this test case on the following version of RI:
[1] jre1.5.0_06
[2] jre1.6.0_07
[3] jre1.6.0_05

All of them works well.


> [classlib][luni] BufferedInputStream can not be closed in another thread
> ------------------------------------------------------------------------
>
>                 Key: HARMONY-6014
>                 URL: https://issues.apache.org/jira/browse/HARMONY-6014
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>    Affects Versions: 5.0M7
>            Reporter: Kevin Zhou
>            Assignee: Sean Qiu
>             Fix For: 5.0M8
>
>         Attachments: HARMONY-6014.diff
>
>   Original Estimate: 24h
>  Remaining Estimate: 24h
>
> Give the following test scenario [1], it start BufferedInputStream object in the main thread, and try to close it in another thread.
> HARMONY fails to close it since the main thread can still read bytes from the buffer.
> [1] 
> public void test_BufferedInputStream_close() {
>         InputStream inputStream = new InputStream() {
>             Object lock = new Object();
>             public int read() {
>                 return 1;
>             }
>             public int read(byte[] buf, int offset, int length) {
>                 synchronized (lock) {
>                     try {
>                         lock.wait(3000);
>                     } catch (InterruptedException e) {
>                         // Ignore
>                     }
>                 }
>                 return 1;
>             }
>             public void close() {
>                 synchronized (lock) {
>                     lock.notifyAll();
>                 }
>             }
>         };
>         final BufferedInputStream buffer = new BufferedInputStream(inputStream);
>         Runnable runnable = new Runnable() {
>             public void run() {
>                 try {
>                     Thread.sleep(1000);
>                     buffer.close();
>                 } catch (Exception e) {
>                     // Ignored
>                 }
>             }
>         };
>         new Thread(runnable).start();
>         try {
>             buffer.read(new byte[100], 0, 99);
>             fail("Should throw IOException");
>         } catch (IOException e) {
>             // Expected
>         }
>     }

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


[jira] Updated: (HARMONY-6014) [classlib][luni] BufferedInputStream can not be closed in another thread

Posted by "Tim Ellison (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HARMONY-6014?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Tim Ellison updated HARMONY-6014:
---------------------------------

    Attachment: stream.patch

Here's a patch (stream.patch) that mostly does the right thing, but what a pain!

We have to keep local copies around and check constantly that the inst var has not been invalidated.  There is one loop left, which is the point at which we update buf with a new larger buffer.  I don't see how we can do this without a race condition with a potential unsynchronized close()

> [classlib][luni] BufferedInputStream can not be closed in another thread
> ------------------------------------------------------------------------
>
>                 Key: HARMONY-6014
>                 URL: https://issues.apache.org/jira/browse/HARMONY-6014
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>    Affects Versions: 5.0M7
>            Reporter: Kevin Zhou
>            Assignee: Sean Qiu
>             Fix For: 5.0M8
>
>         Attachments: HARMONY-6014.diff, stream.patch
>
>   Original Estimate: 24h
>  Remaining Estimate: 24h
>
> Give the following test scenario [1], it start BufferedInputStream object in the main thread, and try to close it in another thread.
> HARMONY fails to close it since the main thread can still read bytes from the buffer.
> [1] 
> public void test_BufferedInputStream_close() {
>         InputStream inputStream = new InputStream() {
>             Object lock = new Object();
>             public int read() {
>                 return 1;
>             }
>             public int read(byte[] buf, int offset, int length) {
>                 synchronized (lock) {
>                     try {
>                         lock.wait(3000);
>                     } catch (InterruptedException e) {
>                         // Ignore
>                     }
>                 }
>                 return 1;
>             }
>             public void close() {
>                 synchronized (lock) {
>                     lock.notifyAll();
>                 }
>             }
>         };
>         final BufferedInputStream buffer = new BufferedInputStream(inputStream);
>         Runnable runnable = new Runnable() {
>             public void run() {
>                 try {
>                     Thread.sleep(1000);
>                     buffer.close();
>                 } catch (Exception e) {
>                     // Ignored
>                 }
>             }
>         };
>         new Thread(runnable).start();
>         try {
>             buffer.read(new byte[100], 0, 99);
>             fail("Should throw IOException");
>         } catch (IOException e) {
>             // Expected
>         }
>     }

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


[jira] Reopened: (HARMONY-6014) [classlib][luni] BufferedInputStream can not be closed in another thread

Posted by "Sean Qiu (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HARMONY-6014?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Sean Qiu reopened HARMONY-6014:
-------------------------------

      Assignee: Tim Ellison  (was: Sean Qiu)

This issue hasn't been completed fixed yet.
Need more investigation.

> [classlib][luni] BufferedInputStream can not be closed in another thread
> ------------------------------------------------------------------------
>
>                 Key: HARMONY-6014
>                 URL: https://issues.apache.org/jira/browse/HARMONY-6014
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>    Affects Versions: 5.0M7
>            Reporter: Kevin Zhou
>            Assignee: Tim Ellison
>             Fix For: 5.0M8
>
>         Attachments: HARMONY-6014.diff, stream.patch
>
>   Original Estimate: 24h
>  Remaining Estimate: 24h
>
> Give the following test scenario [1], it start BufferedInputStream object in the main thread, and try to close it in another thread.
> HARMONY fails to close it since the main thread can still read bytes from the buffer.
> [1] 
> public void test_BufferedInputStream_close() {
>         InputStream inputStream = new InputStream() {
>             Object lock = new Object();
>             public int read() {
>                 return 1;
>             }
>             public int read(byte[] buf, int offset, int length) {
>                 synchronized (lock) {
>                     try {
>                         lock.wait(3000);
>                     } catch (InterruptedException e) {
>                         // Ignore
>                     }
>                 }
>                 return 1;
>             }
>             public void close() {
>                 synchronized (lock) {
>                     lock.notifyAll();
>                 }
>             }
>         };
>         final BufferedInputStream buffer = new BufferedInputStream(inputStream);
>         Runnable runnable = new Runnable() {
>             public void run() {
>                 try {
>                     Thread.sleep(1000);
>                     buffer.close();
>                 } catch (Exception e) {
>                     // Ignored
>                 }
>             }
>         };
>         new Thread(runnable).start();
>         try {
>             buffer.read(new byte[100], 0, 99);
>             fail("Should throw IOException");
>         } catch (IOException e) {
>             // Expected
>         }
>     }

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


[jira] Commented: (HARMONY-6014) [classlib][luni] BufferedInputStream can not be closed in another thread

Posted by "Kevin Zhou (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HARMONY-6014?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12647228#action_12647228 ] 

Kevin Zhou commented on HARMONY-6014:
-------------------------------------

Only Harmony fails while RI works well.

> [classlib][luni] BufferedInputStream can not be closed in another thread
> ------------------------------------------------------------------------
>
>                 Key: HARMONY-6014
>                 URL: https://issues.apache.org/jira/browse/HARMONY-6014
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>    Affects Versions: 5.0M7
>            Reporter: Kevin Zhou
>            Assignee: Sean Qiu
>             Fix For: 5.0M8
>
>         Attachments: HARMONY-6014.diff
>
>   Original Estimate: 24h
>  Remaining Estimate: 24h
>
> Give the following test scenario [1], it start BufferedInputStream object in the main thread, and try to close it in another thread.
> HARMONY fails to close it since the main thread can still read bytes from the buffer.
> [1] 
> public void test_BufferedInputStream_close() {
>         InputStream inputStream = new InputStream() {
>             Object lock = new Object();
>             public int read() {
>                 return 1;
>             }
>             public int read(byte[] buf, int offset, int length) {
>                 synchronized (lock) {
>                     try {
>                         lock.wait(3000);
>                     } catch (InterruptedException e) {
>                         // Ignore
>                     }
>                 }
>                 return 1;
>             }
>             public void close() {
>                 synchronized (lock) {
>                     lock.notifyAll();
>                 }
>             }
>         };
>         final BufferedInputStream buffer = new BufferedInputStream(inputStream);
>         Runnable runnable = new Runnable() {
>             public void run() {
>                 try {
>                     Thread.sleep(1000);
>                     buffer.close();
>                 } catch (Exception e) {
>                     // Ignored
>                 }
>             }
>         };
>         new Thread(runnable).start();
>         try {
>             buffer.read(new byte[100], 0, 99);
>             fail("Should throw IOException");
>         } catch (IOException e) {
>             // Expected
>         }
>     }

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


[jira] Commented: (HARMONY-6014) [classlib][luni] BufferedInputStream can not be closed in another thread

Posted by "Nathan Beyer (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HARMONY-6014?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12647169#action_12647169 ] 

Nathan Beyer commented on HARMONY-6014:
---------------------------------------

Does this test fail on a RI? If so, which version?

> [classlib][luni] BufferedInputStream can not be closed in another thread
> ------------------------------------------------------------------------
>
>                 Key: HARMONY-6014
>                 URL: https://issues.apache.org/jira/browse/HARMONY-6014
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>    Affects Versions: 5.0M7
>            Reporter: Kevin Zhou
>            Assignee: Sean Qiu
>             Fix For: 5.0M8
>
>         Attachments: HARMONY-6014.diff
>
>   Original Estimate: 24h
>  Remaining Estimate: 24h
>
> Give the following test scenario [1], it start BufferedInputStream object in the main thread, and try to close it in another thread.
> HARMONY fails to close it since the main thread can still read bytes from the buffer.
> [1] 
> public void test_BufferedInputStream_close() {
>         InputStream inputStream = new InputStream() {
>             Object lock = new Object();
>             public int read() {
>                 return 1;
>             }
>             public int read(byte[] buf, int offset, int length) {
>                 synchronized (lock) {
>                     try {
>                         lock.wait(3000);
>                     } catch (InterruptedException e) {
>                         // Ignore
>                     }
>                 }
>                 return 1;
>             }
>             public void close() {
>                 synchronized (lock) {
>                     lock.notifyAll();
>                 }
>             }
>         };
>         final BufferedInputStream buffer = new BufferedInputStream(inputStream);
>         Runnable runnable = new Runnable() {
>             public void run() {
>                 try {
>                     Thread.sleep(1000);
>                     buffer.close();
>                 } catch (Exception e) {
>                     // Ignored
>                 }
>             }
>         };
>         new Thread(runnable).start();
>         try {
>             buffer.read(new byte[100], 0, 99);
>             fail("Should throw IOException");
>         } catch (IOException e) {
>             // Expected
>         }
>     }

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


[jira] Commented: (HARMONY-6014) [classlib][luni] BufferedInputStream can not be closed in another thread

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

Regis Xu commented on HARMONY-6014:
-----------------------------------

Are anyone interested to review the patch hy-6014.regis.diff?

> [classlib][luni] BufferedInputStream can not be closed in another thread
> ------------------------------------------------------------------------
>
>                 Key: HARMONY-6014
>                 URL: https://issues.apache.org/jira/browse/HARMONY-6014
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>    Affects Versions: 5.0M7
>            Reporter: Kevin Zhou
>            Assignee: Tim Ellison
>             Fix For: 5.0M8
>
>         Attachments: HARMONY-6014.diff, hy-6014.regis.diff, stream.patch
>
>   Original Estimate: 24h
>  Remaining Estimate: 24h
>
> Give the following test scenario [1], it start BufferedInputStream object in the main thread, and try to close it in another thread.
> HARMONY fails to close it since the main thread can still read bytes from the buffer.
> [1] 
> public void test_BufferedInputStream_close() {
>         InputStream inputStream = new InputStream() {
>             Object lock = new Object();
>             public int read() {
>                 return 1;
>             }
>             public int read(byte[] buf, int offset, int length) {
>                 synchronized (lock) {
>                     try {
>                         lock.wait(3000);
>                     } catch (InterruptedException e) {
>                         // Ignore
>                     }
>                 }
>                 return 1;
>             }
>             public void close() {
>                 synchronized (lock) {
>                     lock.notifyAll();
>                 }
>             }
>         };
>         final BufferedInputStream buffer = new BufferedInputStream(inputStream);
>         Runnable runnable = new Runnable() {
>             public void run() {
>                 try {
>                     Thread.sleep(1000);
>                     buffer.close();
>                 } catch (Exception e) {
>                     // Ignored
>                 }
>             }
>         };
>         new Thread(runnable).start();
>         try {
>             buffer.read(new byte[100], 0, 99);
>             fail("Should throw IOException");
>         } catch (IOException e) {
>             // Expected
>         }
>     }

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


[jira] Updated: (HARMONY-6014) [classlib][luni] BufferedInputStream can not be closed in another thread

Posted by "Kevin Zhou (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HARMONY-6014?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Kevin Zhou updated HARMONY-6014:
--------------------------------

    Attachment: HARMONY-6014.diff

Would you please help to try this patch?

> [classlib][luni] BufferedInputStream can not be closed in another thread
> ------------------------------------------------------------------------
>
>                 Key: HARMONY-6014
>                 URL: https://issues.apache.org/jira/browse/HARMONY-6014
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>    Affects Versions: 5.0M7
>            Reporter: Kevin Zhou
>             Fix For: 5.0M8
>
>         Attachments: HARMONY-6014.diff
>
>   Original Estimate: 24h
>  Remaining Estimate: 24h
>
> Give the following test scenario [1], it start BufferedInputStream object in the main thread, and try to close it in another thread.
> HARMONY fails to close it since the main thread can still read bytes from the buffer.
> [1] 
> public void test_BufferedInputStream_close() {
>         InputStream inputStream = new InputStream() {
>             Object lock = new Object();
>             public int read() {
>                 return 1;
>             }
>             public int read(byte[] buf, int offset, int length) {
>                 synchronized (lock) {
>                     try {
>                         lock.wait(3000);
>                     } catch (InterruptedException e) {
>                         // Ignore
>                     }
>                 }
>                 return 1;
>             }
>             public void close() {
>                 synchronized (lock) {
>                     lock.notifyAll();
>                 }
>             }
>         };
>         final BufferedInputStream buffer = new BufferedInputStream(inputStream);
>         Runnable runnable = new Runnable() {
>             public void run() {
>                 try {
>                     Thread.sleep(1000);
>                     buffer.close();
>                 } catch (Exception e) {
>                     // Ignored
>                 }
>             }
>         };
>         new Thread(runnable).start();
>         try {
>             buffer.read(new byte[100], 0, 99);
>             fail("Should throw IOException");
>         } catch (IOException e) {
>             // Expected
>         }
>     }

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


Re: [classlib][luni] BufferedInputStream can not be closed in another thread (HARMONY-6014)

Posted by Regis <xu...@gmail.com>.
Tim Ellison wrote:
> Kevin Zhou wrote:
>> I think Regis's suggestion, to shrink the synchronized block only on buff
>> object, is good, as for one aspect of performance improvement.
>> But we already confirmed that RI synchronizes its BufferedInputStream.read()
>> method.
>> We have to follows the behaviors in the short terms to be compatible with
>> RI.
> 
> I don't think it will help (or I don't understand your suggestion).
> 
> The goal is to allow the close() to occur asynchronously to a read(),
> while maintaining the coherency of the buffered input stream.
> 
> This is most likely to be an issue when you have underlying sockets,
> where the read will block but you can still close it.
> 
> The example below will work on the RI, but block indefinitely on Harmony:
> 
>   ServerSocket server = new ServerSocket(0);
>   Socket client = new Socket(InetAddress.getLocalHost(),
> server.getLocalPort());
> 
>   final BufferedInputStream bis = new
> BufferedInputStream(client.getInputStream());
> 
>   Thread reader = new Thread(new Runnable() {
>       public void run() {
>           System.out.println("Reading...");
>           try {
>               bis.read();
>           } catch (IOException e) {
>               throw new RuntimeException(e);
>           }
>       }
>   });
> 
>   // Wait for the read to block
>   reader.start();
>   System.out.println("Waiting...");
>   Thread.sleep(1000); // Urgh
> 
>   System.out.println("Closing...");
>   bis.close();
> 
>   client.close();
>   server.close();
> 
> 
How about this patch? It use the same way as Selector.close()

Index: modules/luni/META-INF/MANIFEST.MF
=====================================================================
--- modules/luni/META-INF/MANIFEST.MF
+++ modules/luni/META-INF/MANIFEST.MF
@@ -22,6 +22,7 @@ Import-Package: com.ibm.icu.lang,
   java.security,
   java.security.cert,
   java.text,
+ java.util.concurrent.atomic,
   java.util.jar,
   java.util.regex,
   java.util.zip,
Index: modules/luni/src/main/java/java/io/BufferedReader.java
=====================================================================
--- modules/luni/src/main/java/java/io/BufferedReader.java
+++ modules/luni/src/main/java/java/io/BufferedReader.java
@@ -17,6 +17,8 @@

  package java.io;

+import java.util.concurrent.atomic.AtomicBoolean;
+
  import org.apache.harmony.luni.util.Msg;

  /**
@@ -51,6 +53,8 @@ public class BufferedReader extends Reader {

      private int pos;

+    private final AtomicBoolean isOpen = new AtomicBoolean(true);
+
      /**
       * Constructs a new BufferedReader on the Reader <code>in</code>. The
       * default buffer size (8K) is allocated and all reads can now be 
filtered
@@ -96,9 +100,9 @@ public class BufferedReader extends Reader {
       */
      @Override
      public void close() throws IOException {
-        synchronized (lock) {
-            if (!isClosed()) {
-                in.close();
+        if (isOpen.getAndSet(false)) {
+            in.close();
+            synchronized (lock) {
                  buf = null;
              }
          }
@@ -143,7 +147,7 @@ public class BufferedReader extends Reader {
       *         otherwise
       */
      private boolean isClosed() {
-        return buf == null;
+        return !isOpen.get();
      }

      /**


-- 
Best Regards,
Regis.

Re: [classlib][luni] BufferedInputStream can not be closed in another thread (HARMONY-6014)

Posted by Tim Ellison <t....@gmail.com>.
Kevin Zhou wrote:
> I think Regis's suggestion, to shrink the synchronized block only on buff
> object, is good, as for one aspect of performance improvement.
> But we already confirmed that RI synchronizes its BufferedInputStream.read()
> method.
> We have to follows the behaviors in the short terms to be compatible with
> RI.

I don't think it will help (or I don't understand your suggestion).

The goal is to allow the close() to occur asynchronously to a read(),
while maintaining the coherency of the buffered input stream.

This is most likely to be an issue when you have underlying sockets,
where the read will block but you can still close it.

The example below will work on the RI, but block indefinitely on Harmony:

  ServerSocket server = new ServerSocket(0);
  Socket client = new Socket(InetAddress.getLocalHost(),
server.getLocalPort());

  final BufferedInputStream bis = new
BufferedInputStream(client.getInputStream());

  Thread reader = new Thread(new Runnable() {
      public void run() {
          System.out.println("Reading...");
          try {
              bis.read();
          } catch (IOException e) {
              throw new RuntimeException(e);
          }
      }
  });

  // Wait for the read to block
  reader.start();
  System.out.println("Waiting...");
  Thread.sleep(1000); // Urgh

  System.out.println("Closing...");
  bis.close();

  client.close();
  server.close();


Re: [classlib][luni] BufferedInputStream can not be closed in another thread (HARMONY-6014)

Posted by Kevin Zhou <zh...@gmail.com>.
I think Regis's suggestion, to shrink the synchronized block only on buff
object, is good, as for one aspect of performance improvement.
But we already confirmed that RI synchronizes its BufferedInputStream.read()
method.
We have to follows the behaviors in the short terms to be compatible with
RI.

On Mon, Nov 17, 2008 at 6:42 PM, Regis <xu...@gmail.com> wrote:

>
>
> Tim Ellison wrote:
>
>> Regis wrote:
>>
>>> I just read the spec, it doesn't say the read method is synchronized or
>>> thread-safe.
>>>
>>
>> Agreed.  The class description doesn't say anything about multiple
>> threads.
>>
>>  I think BufferedInputStream just need to keep itself status consistent,
>>> he never know how is the InputStream implemented, it's better to left
>>> synchronous/asynchronous problems handled by the wrapped stream.
>>>
>>
>> Well at the moment we have the methods on BufferedInputStream marked as
>> synchronized.  That will ensure the consistency of the state in the
>> buffered stream, and in the wrapped stream.
>>
>> Relaxing the sync on close() would pass through the multi-threading
>> problems to the wrapped stream, but we still need to ensure the buffered
>> stream is consistent, and that is non-trivial too (see my patch on the
>> JIRA).
>>
> I think The consistency of wrapped stream should be assured by itself,
> BufferedInputStream should be transparent on this. But I tested, that RI
> also synchronized the read method. So if we follow RI, I think the patch may
> be the best solution.
>
>
> Best Regards,
> Regis.
>
>
>> Regards,
>> Tim
>>
>>

Re: [classlib][luni] BufferedInputStream can not be closed in another thread (HARMONY-6014)

Posted by Regis <xu...@gmail.com>.

Tim Ellison wrote:
> Regis wrote:
>> I just read the spec, it doesn't say the read method is synchronized or
>> thread-safe.
> 
> Agreed.  The class description doesn't say anything about multiple threads.
> 
>> I think BufferedInputStream just need to keep itself status consistent,
>> he never know how is the InputStream implemented, it's better to left
>> synchronous/asynchronous problems handled by the wrapped stream.
> 
> Well at the moment we have the methods on BufferedInputStream marked as
> synchronized.  That will ensure the consistency of the state in the
> buffered stream, and in the wrapped stream.
> 
> Relaxing the sync on close() would pass through the multi-threading
> problems to the wrapped stream, but we still need to ensure the buffered
> stream is consistent, and that is non-trivial too (see my patch on the
> JIRA).
I think The consistency of wrapped stream should be assured by itself, 
BufferedInputStream should be transparent on this. But I tested, that RI 
also synchronized the read method. So if we follow RI, I think the patch 
may be the best solution.

Best Regards,
Regis.

> 
> Regards,
> Tim
> 

Re: [classlib][luni] BufferedInputStream can not be closed in another thread (HARMONY-6014)

Posted by Tim Ellison <t....@gmail.com>.
Regis wrote:
> I just read the spec, it doesn't say the read method is synchronized or
> thread-safe.

Agreed.  The class description doesn't say anything about multiple threads.

> I think BufferedInputStream just need to keep itself status consistent,
> he never know how is the InputStream implemented, it's better to left
> synchronous/asynchronous problems handled by the wrapped stream.

Well at the moment we have the methods on BufferedInputStream marked as
synchronized.  That will ensure the consistency of the state in the
buffered stream, and in the wrapped stream.

Relaxing the sync on close() would pass through the multi-threading
problems to the wrapped stream, but we still need to ensure the buffered
stream is consistent, and that is non-trivial too (see my patch on the
JIRA).

Regards,
Tim

Re: [classlib][luni] BufferedInputStream can not be closed in another thread (HARMONY-6014)

Posted by Regis <xu...@gmail.com>.

Tim Ellison wrote:
> Regis wrote:
>> Tim Ellison wrote:
>>> The new code is quite gross -- I really wonder what the use case is that
>>> means close() should be unsynchronized??
>> One thread block on read, another one want to close the stream
>> immediately, if read and close are both synchronized, the second one
>> would be blocked until the first one read something.
> 
> I understand the hypothesis, but why would you have a blocking read and
> non-blocking close?  The buffer input stream wraps an underlying stream,
> it doesn't make sense to me to make it part synchronized and part not.
> 
>> I think, here the question is why we synchronized the whole read method.
> 
> As you showed, the read method in the RI is synchronized.  We are trying
> to be compatible -- otherwise we'd just leave the close method synchronized.
> 
I just read the spec, it doesn't say the read method is synchronized or 
thread-safe.

>> Holding one lock and blocking on IO is dangerous, especially holding
>> "this" lock. Could we use private lock for synchronizing buffer?
> 
> 'dangerous'? It keeps things consistent, since you can't as for
> available() or close() during a read().  Are you suggesting we
> deliberately deviate from compatibility in this case?  Does anyone rely
> upon the "asynchronous" close behavior?
I think BufferedInputStream just need to keep itself status consistent, 
he never know how is the InputStream implemented, it's better to left 
synchronous/asynchronous problems handled by the wrapped stream.

Best Regards,
Regis.
> 
> Regards,
> Tim
> 
> 

Re: [classlib][luni] BufferedInputStream can not be closed in another thread (HARMONY-6014)

Posted by Tim Ellison <t....@gmail.com>.
Nathan Beyer wrote:
> The close() may not be completely unsynchronized - the entire method
> isn't synchronized, but the implementation could still be locking
> within at certain critical points.
> 
> In any case, I'm not sure what the real guarantees of InputStream and
> BufferedInputStream should be. The spec is very quiet about the use in
> a concurrent use case.
> 
> How much do we really need to guarantee? The original bug's test case
> seems overly contrived. Is there any real use case that this has shown
> up in?

Right, the spec is not helpful here.

Regis' test case does look contrived, and I don't think we have a real
world example of when an asynchronous close() is required, but I can
imagine that it would be true for socket input streams.

Again, a contrived case, but imagine that you got an input stream from a
URLConnection, and wrapped it in a BufferedInputStream.  You could be
blocked on the read() in one thread, and decide to close() the stream in
another...

Regards,
Tim


Re: [classlib][luni] BufferedInputStream can not be closed in another thread (HARMONY-6014)

Posted by Nathan Beyer <nd...@apache.org>.
The close() may not be completely unsynchronized - the entire method
isn't synchronized, but the implementation could still be locking
within at certain critical points.

In any case, I'm not sure what the real guarantees of InputStream and
BufferedInputStream should be. The spec is very quiet about the use in
a concurrent use case.

How much do we really need to guarantee? The original bug's test case
seems overly contrived. Is there any real use case that this has shown
up in?

-Nathan

On Fri, Nov 14, 2008 at 6:58 AM, Tim Ellison <t....@gmail.com> wrote:
> Regis wrote:
>> Tim Ellison wrote:
>>> The new code is quite gross -- I really wonder what the use case is that
>>> means close() should be unsynchronized??
>>
>> One thread block on read, another one want to close the stream
>> immediately, if read and close are both synchronized, the second one
>> would be blocked until the first one read something.
>
> I understand the hypothesis, but why would you have a blocking read and
> non-blocking close?  The buffer input stream wraps an underlying stream,
> it doesn't make sense to me to make it part synchronized and part not.
>
>> I think, here the question is why we synchronized the whole read method.
>
> As you showed, the read method in the RI is synchronized.  We are trying
> to be compatible -- otherwise we'd just leave the close method synchronized.
>
>> Holding one lock and blocking on IO is dangerous, especially holding
>> "this" lock. Could we use private lock for synchronizing buffer?
>
> 'dangerous'? It keeps things consistent, since you can't as for
> available() or close() during a read().  Are you suggesting we
> deliberately deviate from compatibility in this case?  Does anyone rely
> upon the "asynchronous" close behavior?
>
> Regards,
> Tim
>
>

Re: [classlib][luni] BufferedInputStream can not be closed in another thread (HARMONY-6014)

Posted by Tim Ellison <t....@gmail.com>.
Regis wrote:
> Tim Ellison wrote:
>> The new code is quite gross -- I really wonder what the use case is that
>> means close() should be unsynchronized??
>
> One thread block on read, another one want to close the stream
> immediately, if read and close are both synchronized, the second one
> would be blocked until the first one read something.

I understand the hypothesis, but why would you have a blocking read and
non-blocking close?  The buffer input stream wraps an underlying stream,
it doesn't make sense to me to make it part synchronized and part not.

> I think, here the question is why we synchronized the whole read method.

As you showed, the read method in the RI is synchronized.  We are trying
to be compatible -- otherwise we'd just leave the close method synchronized.

> Holding one lock and blocking on IO is dangerous, especially holding
> "this" lock. Could we use private lock for synchronizing buffer?

'dangerous'? It keeps things consistent, since you can't as for
available() or close() during a read().  Are you suggesting we
deliberately deviate from compatibility in this case?  Does anyone rely
upon the "asynchronous" close behavior?

Regards,
Tim


Re: [classlib][luni] BufferedInputStream can not be closed in another thread (HARMONY-6014)

Posted by Regis <xu...@gmail.com>.

Tim Ellison wrote:
> I realize that I'm talking to myself, but hey... :-)
> 
> Tim Ellison wrote:
>> However, close() also has the side effect of closing the source 'in'
>> stream, so we have to be prepared for that to be null at any
>> (unsynchronized) point too.  The 'in' variable needs to be declared
>> volatile in FilterInputStream (as per spec too) -- but the problem is
>> that, unlike buf, simply holding a local reference to the stream doesn't
>> help if somebody changes it's state to closed since we can't continue to
>> rely on skip() and available() etc. working.
>>
>> This is messy.  I don't see how we can get a consistent state on 'in'?
> 
> On further thought, the local reference to the 'in' stream can only be
> invalidated by the stream being closed, in which case our attempt to
> call available() or read() should [1] simply result in an IOException
> which is what we want anyway.
> 
> I've uploaded a patch [2] that enables the close() to be unsynchronized.
>  There is still one race condition in there, when we are replacing the
> buf with a longer byte array.  It may be set to null as we are replacing
> it, and we would be left in an inconsistent state.
> 
> The new code is quite gross -- I really wonder what the use case is that
> means close() should be unsynchronized??
One thread block on read, another one want to close the stream 
immediately, if read and close are both synchronized, the second one 
would be blocked until the first one read something.

I think, here the question is why we synchronized the whole read method. 
Holding one lock and blocking on IO is dangerous, especially holding 
"this" lock. Could we use private lock for synchronizing buffer?
> 
> [1] it could be subclassed to do something weird, but let's assume not.
> [2] https://issues.apache.org/jira/browse/HARMONY-6014
> 
> Regards,
> Tim
> 

Re: [classlib][luni] BufferedInputStream can not be closed in another thread (HARMONY-6014)

Posted by Tim Ellison <t....@gmail.com>.
I realize that I'm talking to myself, but hey... :-)

Tim Ellison wrote:
> However, close() also has the side effect of closing the source 'in'
> stream, so we have to be prepared for that to be null at any
> (unsynchronized) point too.  The 'in' variable needs to be declared
> volatile in FilterInputStream (as per spec too) -- but the problem is
> that, unlike buf, simply holding a local reference to the stream doesn't
> help if somebody changes it's state to closed since we can't continue to
> rely on skip() and available() etc. working.
> 
> This is messy.  I don't see how we can get a consistent state on 'in'?

On further thought, the local reference to the 'in' stream can only be
invalidated by the stream being closed, in which case our attempt to
call available() or read() should [1] simply result in an IOException
which is what we want anyway.

I've uploaded a patch [2] that enables the close() to be unsynchronized.
 There is still one race condition in there, when we are replacing the
buf with a longer byte array.  It may be set to null as we are replacing
it, and we would be left in an inconsistent state.

The new code is quite gross -- I really wonder what the use case is that
means close() should be unsynchronized??

[1] it could be subclassed to do something weird, but let's assume not.
[2] https://issues.apache.org/jira/browse/HARMONY-6014

Regards,
Tim

[classlib][luni] BufferedInputStream can not be closed in another thread (HARMONY-6014)

Posted by Tim Ellison <t....@gmail.com>.
Nathan Beyer (JIRA) wrote:
> Can you rework the patch to NOT depend on catching a
> NullPointerException?

Yeah, it is hacky.

> Additionally, since the 'buf' is becoming volatile,

The spec [1] says that it should be volatile, so that is goodness.

> you should use the "copy-to-local" paradigm for that field.
> Essentially, copy the field to a method local variable, then work
> against that variable. You want to reduce the number of direct
> accesses to the volatile field.

Right.  Based on the JIRA report, our goal is now to remove the
synchronized keyword from close().  So we need to make the
unsynchronized closure visible to other threads, and deal with the
effects of an unsynchronized close().

[ Allowing an unsynchronized call to close() seems like a dumb idea to
me, but I guess we have to follow the RI behavior here ... ]

If we agree that we will be using 'buf=null' to indicate that the
buffered stream is closed, then why do we also have a 'closed' boolean?
I suggest we remove that.

Like you say, we must take a local copy of the volatile 'buf' in each
method that uses it, and work with that even if after the stream is closed.

However, close() also has the side effect of closing the source 'in'
stream, so we have to be prepared for that to be null at any
(unsynchronized) point too.  The 'in' variable needs to be declared
volatile in FilterInputStream (as per spec too) -- but the problem is
that, unlike buf, simply holding a local reference to the stream doesn't
help if somebody changes it's state to closed since we can't continue to
rely on skip() and available() etc. working.

This is messy.  I don't see how we can get a consistent state on 'in'?
I'm sure a synchronized close() would have been fine ;-/

[1] http://java.sun.com/j2se/1.5.0/docs/api/java/io/BufferedInputStream.html

Regards,
Tim

-- work in progress

Index: BufferedInputStream.java
===================================================================
--- BufferedInputStream.java	(revision 711277)
+++ BufferedInputStream.java	(working copy)
@@ -32,7 +32,7 @@
     /**
      * The buffer containing the current bytes read from the target
InputStream.
      */
-    protected byte[] buf;
+    protected volatile byte[] buf;

     /**
      * The total number of bytes inside the byte array <code>buf</code>.
@@ -55,8 +55,6 @@
      */
     protected int pos;

-    private boolean closed = false;
-
     /**
      * Constructs a new <code>BufferedInputStream</codeon the InputStream
      * <code>in</code>. The default buffer size (8Kb) is allocated and all
@@ -105,6 +103,7 @@
             // K0059=Stream is closed
             throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
         }
+        // FIXME: 'in' could be invalidated by close()
         return count - pos + in.available();
     }

@@ -116,19 +115,19 @@
      *             If an error occurs attempting to close this stream.
      */
     @Override
-    public synchronized void close() throws IOException {
+    public void close() throws IOException {
+        buf = null;
         if (null != in) {
             super.close();
             in = null;
         }
-        buf = null;
-        closed = true;
     }

-    private int fillbuf() throws IOException {
+    // FIXME: 'in' could be invalidated by close()
+    private int fillbuf(byte[] buffer) throws IOException {
         if (markpos == -1 || (pos - markpos >= marklimit)) {
             /* Mark position not set or exceeded readlimit */
-            int result = in.read(buf);
+            int result = in.read(buffer);
             if (result 0) {
                 markpos = -1;
                 pos = 0;
@@ -136,22 +135,22 @@
             }
             return result;
         }
-        if (markpos == 0 && marklimit buf.length) {
-            /* Increase buffer size to accomodate the readlimit */
-            int newLength = buf.length * 2;
+        if (markpos == 0 && marklimit buffer.length) {
+            /* Increase buffer size to accommodate the readlimit */
+            int newLength = buffer.length * 2;
             if (newLength marklimit) {
                 newLength = marklimit;
             }
             byte[] newbuf = new byte[newLength];
-            System.arraycopy(buf, 0, newbuf, 0, buf.length);
-            buf = newbuf;
+            System.arraycopy(buffer, 0, newbuf, 0, buffer.length);
+            buffer = newbuf;
         } else if (markpos 0) {
-            System.arraycopy(buf, markpos, buf, 0, buf.length - markpos);
+            System.arraycopy(buffer, markpos, buffer, 0, buffer.length
- markpos);
         }
         /* Set the new position and mark position */
         pos -= markpos;
         count = markpos = 0;
-        int bytesread = in.read(buf, pos, buf.length - pos);
+        int bytesread = in.read(buffer, pos, buffer.length - pos);
         count = bytesread <= 0 ? pos : pos + bytesread;
         return bytesread;
     }
@@ -200,19 +199,20 @@
      */
     @Override
     public synchronized int read() throws IOException {
-        if (in == null) {
+        byte[] localBuf = buf;    // buf may be invalidated by an
unsynchronized close()
+        if (localBuf == null) {
             // K0059=Stream is closed
             throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
         }

         /* Are there buffered bytes available? */
-        if (pos >= count && fillbuf() == -1) {
+        if (pos >= count && fillbuf(localBuf) == -1) {
             return -1; /* no, fill buffer */
         }

         /* Did filling the buffer fail with -1 (EOF)? */
         if (count - pos 0) {
-            return buf[pos++] & 0xFF;
+            return localBuf[pos++] & 0xFF;
         }
         return -1;
     }
@@ -239,10 +239,12 @@
      *             If the stream is already closed or another IOException
      *             occurs.
      */
+    // FIXME: 'in' may be invalidated by close()
     @Override
     public synchronized int read(byte[] buffer, int offset, int length)
             throws IOException {
-        if (closed) {
+        byte[] localBuf = buf;    // buf may be invalidated by an
unsynchronized close()
+        if (localBuf == null) {
             // K0059=Stream is closed
             throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
         }
@@ -253,15 +255,12 @@
         if (length == 0) {
             return 0;
         }
-        if (null == buf) {
-            throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
-        }

         int required;
         if (pos < count) {
             /* There are bytes available in the buffer. */
             int copylength = count - pos >= length ? length : count - pos;
-            System.arraycopy(buf, pos, buffer, offset, copylength);
+            System.arraycopy(localBuf, pos, buffer, offset, copylength);
             pos += copylength;
             if (copylength == length || in.available() == 0) {
                 return copylength;
@@ -278,17 +277,17 @@
              * If we're not marked and the required size is greater
than the
              * buffer, simply read the bytes directly bypassing the buffer.
              */
-            if (markpos == -1 && required >= buf.length) {
+            if (markpos == -1 && required >= localBuf.length) {
                 read = in.read(buffer, offset, required);
                 if (read == -1) {
                     return required == length ? -1 : length - required;
                 }
             } else {
-                if (fillbuf() == -1) {
+                if (fillbuf(localBuf) == -1) {
                     return required == length ? -1 : length - required;
                 }
                 read = count - pos >= required ? required : count - pos;
-                System.arraycopy(buf, pos, buffer, offset, read);
+                System.arraycopy(localBuf, pos, buffer, offset, read);
                 pos += read;
             }
             required -= read;
@@ -315,7 +314,7 @@

     @Override
     public synchronized void reset() throws IOException {
-        if (closed) {
+        if (buf == null) {
             // K0059=Stream is closed
             throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$	
         }
@@ -341,7 +340,8 @@
      */
     @Override
     public synchronized long skip(long amount) throws IOException {
-        if (null == in) {
+        byte[] localBuf = buf;    // buf may be invalidated by an
unsynchronized close()
+        if (localBuf == null) {
             // K0059=Stream is closed
             throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
         }
@@ -358,7 +358,7 @@

         if (markpos != -1) {
             if (amount <= marklimit) {
-                if (fillbuf() == -1) {
+                if (fillbuf(localBuf) == -1) {
                     return read;
                 }
                 if (count - pos >= amount - read) {
@@ -372,6 +372,7 @@
             }
             markpos = -1;
         }
+        // FIXME: 'in' may be invalidated by close()
         return read + in.skip(amount - read);
     }
 }

[jira] Commented: (HARMONY-6014) [classlib][luni] BufferedInputStream can not be closed in another thread

Posted by "Nathan Beyer (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HARMONY-6014?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12647306#action_12647306 ] 

Nathan Beyer commented on HARMONY-6014:
---------------------------------------

Thanks

Can you rework the patch to NOT depend on catching a NullPointerException?

Additionally, since the 'buf' is becoming volatile, you should use the "copy-to-local" paradigm for that field. Essentially, copy the field to a method local variable, then work against that variable. You want to reduce the number of direct accesses to the volatile field.

> [classlib][luni] BufferedInputStream can not be closed in another thread
> ------------------------------------------------------------------------
>
>                 Key: HARMONY-6014
>                 URL: https://issues.apache.org/jira/browse/HARMONY-6014
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>    Affects Versions: 5.0M7
>            Reporter: Kevin Zhou
>            Assignee: Sean Qiu
>             Fix For: 5.0M8
>
>         Attachments: HARMONY-6014.diff
>
>   Original Estimate: 24h
>  Remaining Estimate: 24h
>
> Give the following test scenario [1], it start BufferedInputStream object in the main thread, and try to close it in another thread.
> HARMONY fails to close it since the main thread can still read bytes from the buffer.
> [1] 
> public void test_BufferedInputStream_close() {
>         InputStream inputStream = new InputStream() {
>             Object lock = new Object();
>             public int read() {
>                 return 1;
>             }
>             public int read(byte[] buf, int offset, int length) {
>                 synchronized (lock) {
>                     try {
>                         lock.wait(3000);
>                     } catch (InterruptedException e) {
>                         // Ignore
>                     }
>                 }
>                 return 1;
>             }
>             public void close() {
>                 synchronized (lock) {
>                     lock.notifyAll();
>                 }
>             }
>         };
>         final BufferedInputStream buffer = new BufferedInputStream(inputStream);
>         Runnable runnable = new Runnable() {
>             public void run() {
>                 try {
>                     Thread.sleep(1000);
>                     buffer.close();
>                 } catch (Exception e) {
>                     // Ignored
>                 }
>             }
>         };
>         new Thread(runnable).start();
>         try {
>             buffer.read(new byte[100], 0, 99);
>             fail("Should throw IOException");
>         } catch (IOException e) {
>             // Expected
>         }
>     }

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


[jira] Assigned: (HARMONY-6014) [classlib][luni] BufferedInputStream can not be closed in another thread

Posted by "Sean Qiu (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HARMONY-6014?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Sean Qiu reassigned HARMONY-6014:
---------------------------------

    Assignee: Sean Qiu

> [classlib][luni] BufferedInputStream can not be closed in another thread
> ------------------------------------------------------------------------
>
>                 Key: HARMONY-6014
>                 URL: https://issues.apache.org/jira/browse/HARMONY-6014
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>    Affects Versions: 5.0M7
>            Reporter: Kevin Zhou
>            Assignee: Sean Qiu
>             Fix For: 5.0M8
>
>         Attachments: HARMONY-6014.diff
>
>   Original Estimate: 24h
>  Remaining Estimate: 24h
>
> Give the following test scenario [1], it start BufferedInputStream object in the main thread, and try to close it in another thread.
> HARMONY fails to close it since the main thread can still read bytes from the buffer.
> [1] 
> public void test_BufferedInputStream_close() {
>         InputStream inputStream = new InputStream() {
>             Object lock = new Object();
>             public int read() {
>                 return 1;
>             }
>             public int read(byte[] buf, int offset, int length) {
>                 synchronized (lock) {
>                     try {
>                         lock.wait(3000);
>                     } catch (InterruptedException e) {
>                         // Ignore
>                     }
>                 }
>                 return 1;
>             }
>             public void close() {
>                 synchronized (lock) {
>                     lock.notifyAll();
>                 }
>             }
>         };
>         final BufferedInputStream buffer = new BufferedInputStream(inputStream);
>         Runnable runnable = new Runnable() {
>             public void run() {
>                 try {
>                     Thread.sleep(1000);
>                     buffer.close();
>                 } catch (Exception e) {
>                     // Ignored
>                 }
>             }
>         };
>         new Thread(runnable).start();
>         try {
>             buffer.read(new byte[100], 0, 99);
>             fail("Should throw IOException");
>         } catch (IOException e) {
>             // Expected
>         }
>     }

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