You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@axis.apache.org by ve...@apache.org on 2010/06/06 13:16:00 UTC

svn commit: r951855 - /axis/axis2/java/transports/trunk/modules/testkit/src/main/java/org/apache/axis2/transport/testkit/util/PortAllocator.java

Author: veithen
Date: Sun Jun  6 11:16:00 2010
New Revision: 951855

URL: http://svn.apache.org/viewvc?rev=951855&view=rev
Log:
Improved the PortAllocator so that Maven parallel build mode can be used.

Modified:
    axis/axis2/java/transports/trunk/modules/testkit/src/main/java/org/apache/axis2/transport/testkit/util/PortAllocator.java

Modified: axis/axis2/java/transports/trunk/modules/testkit/src/main/java/org/apache/axis2/transport/testkit/util/PortAllocator.java
URL: http://svn.apache.org/viewvc/axis/axis2/java/transports/trunk/modules/testkit/src/main/java/org/apache/axis2/transport/testkit/util/PortAllocator.java?rev=951855&r1=951854&r2=951855&view=diff
==============================================================================
--- axis/axis2/java/transports/trunk/modules/testkit/src/main/java/org/apache/axis2/transport/testkit/util/PortAllocator.java (original)
+++ axis/axis2/java/transports/trunk/modules/testkit/src/main/java/org/apache/axis2/transport/testkit/util/PortAllocator.java Sun Jun  6 11:16:00 2010
@@ -19,41 +19,126 @@
 
 package org.apache.axis2.transport.testkit.util;
 
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.axis2.transport.testkit.tests.Setup;
-import org.apache.axis2.transport.testkit.tests.Transient;
+import org.apache.axis2.transport.testkit.tests.TearDown;
 
 public class PortAllocator {
+    private static final int BASE_PORT = 9000;
+    private static final int BASE_PORT_INCREMENT = 10;
+    
     public static final PortAllocator INSTANCE = new PortAllocator();
     
-    private static final int basePort = 9000;
+    static class PortRange {
+        private final ServerSocket serverSocket;
+        private final int basePort;
+        private final boolean[] allocated = new boolean[BASE_PORT_INCREMENT-1];
+        
+        PortRange(ServerSocket serverSocket) {
+            this.serverSocket = serverSocket;
+            basePort = serverSocket.getLocalPort();
+        }
+        
+        /**
+         * Allocate a port in this range.
+         * 
+         * @return the allocated port, or -1 if there are no more available ports
+         */
+        int allocatePort() {
+            for (int i=0; i<BASE_PORT_INCREMENT-1; i++) {
+                if (!allocated[i]) {
+                    allocated[i] = true;
+                    return basePort + i + 1;
+                }
+            }
+            return -1;
+        }
+        
+        /**
+         * Determine if the given port belongs to the range.
+         * 
+         * @return <code>true</code> if the port belongs to the range; <code>false</code> otherwise
+         */
+        boolean hasPort(int port) {
+            return port > basePort && port < basePort + BASE_PORT_INCREMENT;
+        }
+        
+        /**
+         * Release the given port.
+         * 
+         * @param port the number of the port to release
+         */
+        void releasePort(int port) {
+            int i = port - basePort - 1;
+            if (!allocated[i]) {
+                throw new IllegalStateException("Port is not allocated");
+            }
+            allocated[i] = false;
+        }
+        
+        void release() {
+            try {
+                serverSocket.close();
+            } catch (IOException ex) {
+                // Ignore
+            }
+        }
+    }
     
-    private @Transient boolean[] allocated;
+    private int basePort;
+    private List<PortRange> ranges;
     
     private PortAllocator() {
     }
     
     @Setup @SuppressWarnings("unused")
     private void setUp() {
-        allocated = new boolean[16];
+        basePort = BASE_PORT;
+        ranges = new ArrayList<PortRange>();
     }
     
-    public int allocatePort() {
-        int len = allocated.length;
-        for (int i=0; i<len; i++) {
-            if (!allocated[i]) {
-                allocated[i] = true;
-                return basePort+i;
+    @TearDown @SuppressWarnings("unused")
+    private void tearDown() throws Exception {
+        for (PortRange range : ranges) {
+            range.release();
+        }
+        ranges = null;
+    }
+    
+    public synchronized int allocatePort() {
+        for (PortRange range : ranges) {
+            int port = range.allocatePort();
+            if (port != -1) {
+                return port;
+            }
+        }
+        while (true) {
+            ServerSocket serverSocket;
+            try {
+                serverSocket = new ServerSocket(basePort);
+            } catch (IOException ex) {
+                serverSocket = null;
+            }
+            basePort += BASE_PORT_INCREMENT;
+            if (serverSocket != null) {
+                PortRange range = new PortRange(serverSocket);
+                ranges.add(range);
+                return range.allocatePort();
             }
         }
-        
-        boolean[] newAllocated = new boolean[len*2];
-        System.arraycopy(allocated, 0, newAllocated, 0, len);
-        newAllocated[len] = true;
-        allocated = newAllocated;
-        return basePort+len;
     }
     
-    public void releasePort(int port) {
-        allocated[port-basePort] = false;
+    public synchronized void releasePort(int port) {
+        for (PortRange range : ranges) {
+            if (range.hasPort(port)) {
+                range.releasePort(port);
+                return;
+            }
+        }
+        throw new IllegalArgumentException("Invalid port number");
     }
 }