From 2d404f6c7ca607bc3eeed86aa6dc05ffabd86ebf Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Fri, 17 Jun 2016 14:21:57 +0300 Subject: Make sure AtmosphereFramework is always properly destroyed (#17581) If servlets have never been initialized, then destroy must happen in the context destroy method Change-Id: If5ea6072f729719c9d2f6b305b0dae2338efd07b --- .../communication/JSR356WebsocketInitializer.java | 32 +++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/server/src/com/vaadin/server/communication/JSR356WebsocketInitializer.java b/server/src/com/vaadin/server/communication/JSR356WebsocketInitializer.java index 6d2843a4fc..fc4dc53714 100644 --- a/server/src/com/vaadin/server/communication/JSR356WebsocketInitializer.java +++ b/server/src/com/vaadin/server/communication/JSR356WebsocketInitializer.java @@ -170,6 +170,20 @@ public class JSR356WebsocketInitializer implements ServletContextListener { return JSR356WebsocketInitializer.class.getName() + "." + servletName; } + /** + * Checks if the given attribute name matches the convention used for + * storing AtmosphereFramework references. + * + * @param attributeName + * the attribute name to check + * @return true if the attribute name matches the convention, + * false otherwise + */ + private static boolean isAtmosphereFrameworkAttribute(String attributeName) { + return attributeName.startsWith(JSR356WebsocketInitializer.class + .getName() + "."); + } + /** * Tries to determine if the given servlet registration refers to a Vaadin * servlet. @@ -202,7 +216,23 @@ public class JSR356WebsocketInitializer implements ServletContextListener { @Override public void contextDestroyed(ServletContextEvent sce) { - // Nothing to do here + // Destroy any AtmosphereFramework instance we have initialized. + // This must be done here to ensure that we cleanup Atmosphere instances + // related to servlets which are never initialized + ServletContext servletContext = sce.getServletContext(); + Enumeration attributeNames = servletContext.getAttributeNames(); + while (attributeNames.hasMoreElements()) { + String attributeName = attributeNames.nextElement(); + if (isAtmosphereFrameworkAttribute(attributeName)) { + Object value = servletContext.getAttribute(attributeName); + if (value instanceof AtmosphereFramework) { + // This might result in calling destroy() twice, once from + // here and once from PushRequestHandler but + // AtmosphereFramework.destroy() deals with that + ((AtmosphereFramework) value).destroy(); + } + } + } } } -- cgit v1.2.3