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.