http-client-branch: fix racy busy loop in graceful SSLEngine closure http-client-branch
authordfuchs
Fri, 27 Apr 2018 11:33:22 +0100
branchhttp-client-branch
changeset 56496 a3937ca907f1
parent 56487 6fc81d0648aa
child 56497 598e0c5b6f8c
http-client-branch: fix racy busy loop in graceful SSLEngine closure
src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java
--- a/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java	Thu Apr 26 14:45:28 2018 +0100
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java	Fri Apr 27 11:33:22 2018 +0100
@@ -545,7 +545,7 @@
 
         @Override
         protected void incoming(List<ByteBuffer> buffers, boolean complete) {
-            assert complete ? buffers ==  Utils.EMPTY_BB_LIST : true;
+            assert complete ? buffers == Utils.EMPTY_BB_LIST : true;
             assert buffers != Utils.EMPTY_BB_LIST ? complete == false : true;
             if (complete) {
                 if (debugw.on()) debugw.log("adding SENTINEL");
@@ -605,6 +605,15 @@
             }
         }
 
+        void triggerWrite() {
+            synchronized (writeList) {
+                if (writeList.isEmpty()) {
+                    writeList.add(HS_TRIGGER);
+                }
+            }
+            scheduler.runOrSchedule();
+        }
+
         private void processData() {
             boolean completing = isCompleting();
 
@@ -837,7 +846,7 @@
                 return false;  // executeTasks will resume activity
             case NEED_WRAP:
                 if (caller == READER) {
-                    writer.addData(HS_TRIGGER);
+                    writer.triggerWrite();
                     return false;
                 }
                 break;
@@ -877,7 +886,6 @@
                     }
                 } while (true);
                 handshakeState.getAndUpdate((current) -> current & ~DOING_TASKS);
-                //writer.addData(HS_TRIGGER);
                 resumeActivity();
             } catch (Throwable t) {
                 handleError(t);
@@ -898,7 +906,17 @@
             if (engine.isInboundDone() && !engine.isOutboundDone()) {
                 if (debug.on()) debug.log("doClosure: close_notify received");
                 close_notify_received = true;
-                doHandshake(r, READER);
+                if (!writer.scheduler.isStopped()) {
+                    doHandshake(r, READER);
+                } else {
+                    // We have received closed notify, but we
+                    // won't be able to send the acknowledgement.
+                    // Nothing more will come from the socket either,
+                    // so mark the reader as completed.
+                    synchronized (reader.readBufferLock) {
+                        reader.completing = true;
+                    }
+                }
             }
         }
         return r;