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"); } }