< prev index next >

src/java.httpclient/share/classes/java/net/http/Http2Connection.java

Print this page
rev 15137 : fix obtainSendWindow deadlock

@@ -95,20 +95,20 @@
     final LinkedList<ByteBuffer> freeList;
     final String key; // for HttpClientImpl.connections map
     FrameReader reader;
 
     // Connection level flow control windows
-    int sendWindow = INITIAL_WINDOW_SIZE;
+    final WindowControl connectionSendWindow = new WindowControl(INITIAL_WINDOW_SIZE);
 
     final static int DEFAULT_FRAME_SIZE = 16 * 1024;
     private static ByteBuffer[] empty = Utils.EMPTY_BB_ARRAY;
 
     final ExecutorWrapper executor;
 
     /**
      * This is established by the protocol spec and the peer will update it with
-     * WINDOW_UPDATEs, which affects the sendWindow.
+     * WINDOW_UPDATEs, which affects the connectionSendWindow.
      */
     final static int INITIAL_WINDOW_SIZE = 64 * 1024 - 1;
 
     // TODO: need list of control frames from other threads
     // that need to be sent

@@ -120,11 +120,11 @@
      * on a Stream.
      */
     Http2Connection(HttpConnection connection, Http2ClientImpl client2,
             Exchange exchange) throws IOException, InterruptedException {
         this.outputQ = new Queue<>();
-        String msg = "Connection send window size " + Integer.toString(sendWindow);
+        String msg = "Connection send window size " + Integer.toString(connectionSendWindow.available());
         Log.logTrace(msg);
 
         //this.initialExchange = exchange;
         assert !(connection instanceof SSLConnection);
         this.connection = connection;

@@ -169,11 +169,11 @@
      */
     Http2Connection(HttpRequestImpl request) throws IOException, InterruptedException {
         InetSocketAddress proxy = request.proxy();
         URI uri = request.uri();
         InetSocketAddress addr = Utils.getAddress(request);
-        String msg = "Connection send window size " + Integer.toString(sendWindow);
+        String msg = "Connection send window size " + Integer.toString(connectionSendWindow.available());
         Log.logTrace(msg);
         this.key = keyFor(uri, proxy);
         this.connection = HttpConnection.getConnection(addr, request, this);
         streams = Collections.synchronizedMap(new HashMap<>());
         this.client = request.client();

@@ -190,33 +190,10 @@
         asyncConn.setAsyncCallbacks(this::asyncReceive, this::shutdown);
         sendConnectionPreface();
         asyncConn.startReading();
     }
 
-    // NEW
-    synchronized void obtainSendWindow(int amount) throws InterruptedException {
-        while (amount > 0) {
-            int n = Math.min(amount, sendWindow);
-            sendWindow -= n;
-            amount -= n;
-            if (amount > 0)
-                wait();
-        }
-    }
-
-    synchronized void updateSendWindow(int amount) {
-        if (sendWindow == 0) {
-            sendWindow += amount;
-            notifyAll();
-        } else
-            sendWindow += amount;
-    }
-
-    synchronized int sendWindow() {
-        return sendWindow;
-    }
-
     static String keyFor(HttpConnection connection) {
         boolean isProxy = connection.isProxied();
         boolean isSecure = connection.isSecure();
         InetSocketAddress addr = connection.address();
 

@@ -464,11 +441,11 @@
         streams.remove(streamid);
     }
 
     private void handleWindowUpdate(WindowUpdateFrame f)
             throws IOException, InterruptedException {
-        updateSendWindow(f.getUpdate());
+        connectionSendWindow.update(f.getUpdate());
     }
 
     private void protocolError(int errorCode)
             throws IOException, InterruptedException {
         GoAwayFrame frame = new GoAwayFrame();
< prev index next >