changeset 780:cf485a78c523

test/java/nio/channels/AsynchronousSocketChannel/Basic.java hangs
author alanb
date Tue, 21 Oct 2008 17:54:26 +0100
parents 84214f4a00a6
children 694942f9c83b
files src/share/classes/sun/nio/ch/PendingFuture.java
diffstat 1 files changed, 23 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/nio/ch/PendingFuture.java	Tue Oct 21 13:40:33 2008 +0100
+++ b/src/share/classes/sun/nio/ch/PendingFuture.java	Tue Oct 21 17:54:26 2008 +0100
@@ -97,12 +97,16 @@
         }
     }
 
-    // return the CountDownLatch, creating it if needed
-    private CountDownLatch latch() {
+    // creates latch if required; return true if caller needs to wait
+    private boolean prepareForWait() {
         synchronized (this) {
-            if (latch == null)
-                latch = new CountDownLatch(1);
-            return latch;
+            if (haveResult) {
+                return false;
+            } else {
+                if (latch == null)
+                    latch = new CountDownLatch(1);
+                return true;
+            }
         }
     }
 
@@ -144,8 +148,11 @@
 
     @Override
     public V get() throws ExecutionException, InterruptedException {
-        if (!haveResult)
-            latch().await();
+        if (!haveResult) {
+            boolean needToWait = prepareForWait();
+            if (needToWait)
+                latch.await();
+        }
         if (exc != null) {
             if (exc == CANCELLED)
                 throw new CancellationException();
@@ -158,9 +165,11 @@
     public V get(long timeout, TimeUnit unit)
         throws ExecutionException, InterruptedException, TimeoutException
     {
-        if (!haveResult)
-            if (!latch().await(timeout, unit))
-                throw new TimeoutException();
+        if (!haveResult) {
+            boolean needToWait = prepareForWait();
+            if (needToWait)
+                if (!latch.await(timeout, unit)) throw new TimeoutException();
+        }
         if (exc != null) {
             if (exc == CANCELLED)
                 throw new CancellationException();
@@ -199,12 +208,12 @@
             // shutdown the executor. To ensure that the completion handler
             // is executed we queue the task while holding the lock.
             if (handler != null) {
-                final CountDownLatch l = latch();
+                prepareForWait();
                 Runnable cancelTask = new Runnable() {
                     public void run() {
                         while (!haveResult) {
                             try {
-                                l.await();
+                                latch.await();
                             } catch (InterruptedException ignore) { }
                         }
                         handler.cancelled(attachment());
@@ -241,7 +250,8 @@
         }
 
         // release waiters (this also releases the invoker)
-        latch().countDown();
+        if (latch != null)
+            latch.countDown();
         return true;
     }
 }