8155888: java/net/httpclient/QuickResponses.java intermittently failed with java.util.ConcurrentModificationException
authormichaelm
Mon, 09 May 2016 10:28:24 +0100
changeset 37816 b06d70715a79
parent 37815 0ecfe8f6500e
child 37817 5fd92fde53db
8155888: java/net/httpclient/QuickResponses.java intermittently failed with java.util.ConcurrentModificationException Reviewed-by: chegar
jdk/test/java/net/httpclient/QuickResponses.java
jdk/test/java/net/httpclient/Server.java
jdk/test/java/net/httpclient/SplitResponse.java
--- a/jdk/test/java/net/httpclient/QuickResponses.java	Mon May 09 17:46:28 2016 +0900
+++ b/jdk/test/java/net/httpclient/QuickResponses.java	Mon May 09 10:28:24 2016 +0100
@@ -71,6 +71,7 @@
     public static void main(String[] args) throws Exception {
         server = new Server(0);
         URI uri = new URI(server.getURL());
+        server.start();
 
         HttpRequest request = HttpRequest.create(uri)
                 .GET();
@@ -79,7 +80,6 @@
         Server.Connection s1 = server.activity();
         s1.send(entireResponse());
 
-
         HttpResponse r = cf1.join();
         if (r.statusCode()!= 200 || !r.body(HttpResponse.asString()).equals(responses[0]))
             throw new RuntimeException("Failed on first response");
--- a/jdk/test/java/net/httpclient/Server.java	Mon May 09 17:46:28 2016 +0900
+++ b/jdk/test/java/net/httpclient/Server.java	Mon May 09 10:28:24 2016 +0100
@@ -21,8 +21,6 @@
  * questions.
  */
 
-//package javaapplication16;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -32,6 +30,7 @@
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Iterator;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -44,13 +43,16 @@
 public class Server extends Thread {
 
     ServerSocket ss;
-    List<Connection> sockets;
+    private final List<Connection> sockets;
+    private final List<Connection> removals;
+    private final List<Connection> additions;
     AtomicInteger counter = new AtomicInteger(0);
 
     // waits up to 20 seconds for something to happen
     // dont use this unless certain activity coming.
     public Connection activity() {
         for (int i = 0; i < 80 * 100; i++) {
+            doRemovalsAndAdditions();
             for (Connection c : sockets) {
                 if (c.poll()) {
                     return c;
@@ -59,11 +61,26 @@
             try {
                 Thread.sleep(250);
             } catch (InterruptedException e) {
+                e.printStackTrace();
             }
         }
         return null;
     }
 
+    private void doRemovalsAndAdditions() {
+        if (removals.isEmpty() && additions.isEmpty())
+            return;
+        Iterator<Connection> i = removals.iterator();
+        while (i.hasNext())
+            sockets.remove(i.next());
+        removals.clear();
+
+        i = additions.iterator();
+        while (i.hasNext())
+            sockets.add(i.next());
+        additions.clear();
+    }
+
     // clears all current connections on Server.
     public void reset() {
         for (Connection c : sockets) {
@@ -84,7 +101,6 @@
             incoming = new ArrayBlockingQueue<>(100);
             setName("Server-Connection");
             setDaemon(true);
-            start();
         }
         final Socket socket;
         final int id;
@@ -210,16 +226,17 @@
             try {
                 socket.close();
             } catch (IOException e) {}
-            sockets.remove(this);
+            removals.add(this);
         }
     }
 
     Server(int port) throws IOException {
         ss = new ServerSocket(port);
         sockets = Collections.synchronizedList(new LinkedList<>());
+        removals = Collections.synchronizedList(new LinkedList<>());
+        additions = Collections.synchronizedList(new LinkedList<>());
         setName("Test-Server");
         setDaemon(true);
-        start();
     }
 
     Server() throws IOException {
@@ -238,6 +255,7 @@
         try {
             ss.close();
         } catch (IOException e) {
+            e.printStackTrace();
         }
         for (Connection c : sockets) {
             c.close();
@@ -250,8 +268,10 @@
             try {
                 Socket s = ss.accept();
                 Connection c = new Connection(s);
-                sockets.add(c);
+                c.start();
+                additions.add(c);
             } catch (IOException e) {
+                e.printStackTrace();
             }
         }
     }
--- a/jdk/test/java/net/httpclient/SplitResponse.java	Mon May 09 17:46:28 2016 +0900
+++ b/jdk/test/java/net/httpclient/SplitResponse.java	Mon May 09 10:28:24 2016 +0100
@@ -68,6 +68,7 @@
     public static void main(String[] args) throws Exception {
         server = new Server(0);
         URI uri = new URI(server.getURL());
+        server.start();
 
         HttpRequest request;
         HttpResponse r;