From 149eda5cb22100f249dc7a8caeaf2a0c42bbd6b8 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Tue, 5 Mar 2024 10:14:38 +0100 Subject: [PATCH] Fix deadlock during HTTP server initialisation --- .../internal/runtime/CmsDeploymentImpl.java | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsDeploymentImpl.java b/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsDeploymentImpl.java index e1c420b82..52f97fd8d 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsDeploymentImpl.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsDeploymentImpl.java @@ -63,12 +63,18 @@ public class CmsDeploymentImpl implements CmsDeployment { public void setHttpServer(HttpServer httpServer) { Objects.requireNonNull(httpServer); - this.httpServer.complete(httpServer); - // create contexts whose handles had already been published - for (String contextPath : httpHandlers.keySet()) { - HttpHandler httpHandler = httpHandlers.get(contextPath); - CmsAuthenticator authenticator = httpAuthenticators.get(contextPath); - createHttpContext(contextPath, httpHandler, authenticator); + if (this.httpServer.isDone()) + throw new IllegalStateException("HTTP server is already set"); + // create contexts whose handlers had already been published + synchronized (httpHandlers) { + synchronized (httpAuthenticators) { + this.httpServer.complete(httpServer); + for (String contextPath : httpHandlers.keySet()) { + HttpHandler httpHandler = httpHandlers.get(contextPath); + CmsAuthenticator authenticator = httpAuthenticators.get(contextPath); + createHttpContext(contextPath, httpHandler, authenticator); + } + } } } @@ -80,9 +86,13 @@ public class CmsDeploymentImpl implements CmsDeployment { } boolean isPublic = Boolean.parseBoolean(properties.get(CmsConstants.CONTEXT_PUBLIC)); CmsAuthenticator authenticator = isPublic ? new PublicCmsAuthenticator() : new CmsAuthenticator(); - httpHandlers.put(contextPath, httpHandler); - httpAuthenticators.put(contextPath, authenticator); - if (httpServer.join() == null) { + synchronized (httpHandlers) { + synchronized (httpAuthenticators) { + httpHandlers.put(contextPath, httpHandler); + httpAuthenticators.put(contextPath, authenticator); + } + } + if (!httpServer.isDone()) { return; } else { createHttpContext(contextPath, httpHandler, authenticator); @@ -95,7 +105,9 @@ public class CmsDeploymentImpl implements CmsDeployment { log.warn("Ignore HTTP context " + contextPath + " as we don't provide an HTTP server"); return; } - HttpContext httpContext = httpServer.join().createContext(contextPath); + if (!this.httpServer.isDone()) + throw new IllegalStateException("HTTP server is not set"); + HttpContext httpContext = httpServer.resultNow().createContext(contextPath); // we want to set the authenticator BEFORE the handler actually becomes active httpContext.setAuthenticator(authenticator); httpContext.setHandler(httpHandler); @@ -107,9 +119,9 @@ public class CmsDeploymentImpl implements CmsDeployment { if (contextPath == null) return; // ignore silently httpHandlers.remove(contextPath); - if (httpServer.join() == null) + if (!httpServer.isDone()) return; - httpServer.join().removeContext(contextPath); + httpServer.resultNow().removeContext(contextPath); log.debug(() -> "Removed handler " + contextPath + " : " + httpHandler.getClass().getName()); } -- 2.30.2