Author: andygumbrecht
Date: Sat Jul 19 13:12:31 2014
New Revision: 1611911
URL: http://svn.apache.org/r1611911
Log:
Don't return the same port as the last one.
Added:
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/test/java/org/apache/openejb/util/NetworkUtilTest.java
Modified:
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/util/NetworkUtil.java
Modified:
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/util/NetworkUtil.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/util/NetworkUtil.java?rev=1611911&r1=1611910&r2=1611911&view=diff
==============================================================================
---
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/util/NetworkUtil.java
(original)
+++
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/util/NetworkUtil.java
Sat Jul 19 13:12:31 2014
@@ -20,48 +20,39 @@ package org.apache.openejb.util;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.Collection;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.locks.ReentrantLock;
public final class NetworkUtil {
+ private static final ReentrantLock lock = new ReentrantLock();
+ private static final AtomicReference<LastPort> lastPort = new
AtomicReference<LastPort>();
+
private NetworkUtil() {
// no-op
}
public static int getNextAvailablePort() {
- return getNextAvailablePort(new int[]{0});
- }
-
- public static int getNextAvailablePort(final int[] portList) {
- int port;
- ServerSocket s = null;
+ final ReentrantLock l = lock;
+ l.lock();
try {
- s = create(portList);
- port = s.getLocalPort();
- } catch (final IOException ioe) {
- port = -1;
+ return getNextAvailablePort(new int[]{0});
} finally {
- if (s != null) {
- try {
- s.close();
- } catch (final Throwable e) {
- //Ignore
- }
- }
+ l.unlock();
}
- return port;
}
- public static int getNextAvailablePort(final int min, final int max, final
Collection<Integer> excepted) {
- int port = -1;
- ServerSocket s = null;
- for (int i = min; i <= max; i++) {
+ public synchronized static int getNextAvailablePort(final int[] portList) {
+
+ final ReentrantLock l = lock;
+ l.lock();
+
+ try {
+ int port;
+ ServerSocket s = null;
try {
- s = create(new int[]{i});
+ s = create(portList);
port = s.getLocalPort();
-
- if (excepted == null || !excepted.contains(port)) {
- break;
- }
} catch (final IOException ioe) {
port = -1;
} finally {
@@ -73,13 +64,61 @@ public final class NetworkUtil {
}
}
}
+
+ lastPort.set(new LastPort(port, System.currentTimeMillis()));
+ return port;
+ } finally {
+ l.unlock();
+ }
+ }
+
+ public synchronized static int getNextAvailablePort(final int min, final
int max, final Collection<Integer> excluded) {
+
+ final ReentrantLock l = lock;
+ l.lock();
+
+ try {
+ int port = -1;
+ ServerSocket s = null;
+ for (int i = min; i <= max; i++) {
+ try {
+ s = create(new int[]{i});
+ port = s.getLocalPort();
+
+ if (excluded == null || !excluded.contains(port)) {
+ break;
+ }
+ } catch (final IOException ioe) {
+ port = -1;
+ } finally {
+ if (s != null) {
+ try {
+ s.close();
+ } catch (final Throwable e) {
+ //Ignore
+ }
+ }
+ }
+ }
+
+ lastPort.set(new LastPort(port, System.currentTimeMillis()));
+ return port;
+ } finally {
+ l.unlock();
}
- return port;
}
private static ServerSocket create(final int[] ports) throws IOException {
for (final int port : ports) {
try {
+
+ final LastPort last = lastPort.get();
+ if (null != last && port == last.port) {
+ if ((System.currentTimeMillis() - last.time) < 10000) {
+ continue;
+ }
+ }
+
return new ServerSocket(port);
} catch (final IOException ex) {
// try next port
@@ -93,4 +132,14 @@ public final class NetworkUtil {
public static String getLocalAddress(final String start, final String end)
{
return start + "localhost:" + getNextAvailablePort() + end;
}
+
+ private static final class LastPort {
+ private final int port;
+ private final long time;
+
+ private LastPort(final int port, final long time) {
+ this.port = port;
+ this.time = time;
+ }
+ }
}
Added:
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/test/java/org/apache/openejb/util/NetworkUtilTest.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/test/java/org/apache/openejb/util/NetworkUtilTest.java?rev=1611911&view=auto
==============================================================================
---
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/test/java/org/apache/openejb/util/NetworkUtilTest.java
(added)
+++
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/test/java/org/apache/openejb/util/NetworkUtilTest.java
Sat Jul 19 13:12:31 2014
@@ -0,0 +1,53 @@
+/**
+ * Tomitribe Confidential
+ * <p/>
+ * Copyright(c) Tomitribe Corporation. 2014
+ * <p/>
+ * The source code for this program is not published or otherwise divested
+ * of its trade secrets, irrespective of what has been deposited with the
+ * U.S. Copyright Office.
+ * <p/>
+ */
+package org.apache.openejb.util;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class NetworkUtilTest {
+
+ @Test
+ public void test() throws Exception {
+
+ final int count = 20;
+ final CountDownLatch latch = new CountDownLatch(count);
+ final long start = System.currentTimeMillis();
+ final CopyOnWriteArrayList<Integer> list = new
CopyOnWriteArrayList<Integer>();
+
+ for (int i = 0; i < count; i++) {
+ final Thread thread = new Thread(new Runnable() {
+ public void run() {
+ final int nextAvailablePort =
NetworkUtil.getNextAvailablePort();
+ if (list.contains(nextAvailablePort)) {
+ if ((System.currentTimeMillis() - start) > 10000)
+ Assert.fail("Got a duplicate port with ten
seconds");
+ } else {
+ list.add(nextAvailablePort);
+ }
+
+ latch.countDown();
+ }
+ }, "test-thread-" + count);
+ thread.setDaemon(false);
+ thread.start();
+ }
+
+ final boolean success = latch.await(15, TimeUnit.SECONDS);
+ Assert.assertTrue(success);
+
+ System.out.println("Thread safe port list = " + list);
+ }
+}