From a2c7a1aafbd30c89e1c857ec8574080dcd83aa52 Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Fri, 31 Jul 2026 17:01:00 +0000
Subject: [PATCH] [#794] Wait for the listen port to be open before returning from connection handler start (#796)
---
opendj-server-legacy/src/main/java/org/opends/server/protocols/http/HTTPConnectionHandler.java | 42 +++++++++++++++++++++++++++++++-----------
1 files changed, 31 insertions(+), 11 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/HTTPConnectionHandler.java b/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/HTTPConnectionHandler.java
index af5b881..7f9cce5 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/HTTPConnectionHandler.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/HTTPConnectionHandler.java
@@ -167,8 +167,10 @@
private final Object waitListen = new Object();
/**
- * The condition guarding {@link #waitListen}: set once the run method has tried to open the
- * socket port, whether it succeeded or not. Guarded by {@link #waitListen}.
+ * Condition predicate for {@link #waitListen}: set once the handler thread
+ * has attempted to start the embedded HTTP server (successfully or not).
+ * Guarded by the {@link #waitListen} monitor; protects the start method
+ * against spurious wakeups.
*/
private boolean listenAttempted;
@@ -574,6 +576,14 @@
return httpServer != null;
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Deliberately left unsynchronized, unlike the overridden {@link Thread#start()}:
+ * the state this method touches is guarded by the {@link #waitListen} monitor, and
+ * holding the thread's own monitor across {@code waitListen.wait()} would block
+ * {@link Thread#join()}.
+ */
@Override
public void start()
{
@@ -584,11 +594,19 @@
{
super.start();
+ final long deadlineNanos = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(LISTEN_TIMEOUT_MS);
try
{
while (!listenAttempted)
{
- waitListen.wait();
+ final long remainingMs = TimeUnit.NANOSECONDS.toMillis(deadlineNanos - System.nanoTime());
+ if (remainingMs <= 0)
+ {
+ logger.error(ERR_CONNHANDLER_TIMEOUT_WAITING_FOR_LISTENER, handlerName,
+ TimeUnit.MILLISECONDS.toSeconds(LISTEN_TIMEOUT_MS));
+ break;
+ }
+ waitListen.wait(remainingMs);
}
}
catch (InterruptedException e)
@@ -654,14 +672,6 @@
try
{
- // At this point, the connection Handler either started correctly or failed
- // to start but the start process should be notified and resume its work in any cases.
- synchronized (waitListen)
- {
- listenAttempted = true;
- waitListen.notifyAll();
- }
-
// If we have gotten here, then we are about to start listening
// for the first time since startup or since we were previously disabled.
// Start the embedded HTTP server
@@ -695,6 +705,16 @@
lastIterationFailed = true;
}
}
+ finally
+ {
+ // At this point, the connection handler either started correctly or failed to start
+ // but the start process should be notified and resume its work in any cases.
+ synchronized (waitListen)
+ {
+ listenAttempted = true;
+ waitListen.notifyAll();
+ }
+ }
}
// Initiate shutdown
--
Gitblit v1.10.0