diff --git a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java index 08f0c5047aa..54dcf423570 100644 --- a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java +++ b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java @@ -653,11 +653,11 @@ protected void exitScope(Request request, Context lastContext, ClassLoader lastL */ protected void notifyExitScope(Request request) { - for (int i = _contextListeners.size(); i-- > 0; ) + for (ContextScopeListener listener : TypeUtil.reverse(_contextListeners)) { try { - _contextListeners.get(i).exitScope(_context, request); + listener.exitScope(_context, request); } catch (Throwable e) { diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ConcurrentPool.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ConcurrentPool.java index c96a75f6c23..dba38e2ef4f 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ConcurrentPool.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ConcurrentPool.java @@ -79,36 +79,6 @@ public ConcurrentPool(StrategyType strategyType, int maxSize) this(strategyType, maxSize, pooled -> 1); } - /** - *

Creates an instance with the specified strategy.

- * - * @param strategyType the strategy to used to lookup entries - * @param maxSize the maximum number of pooled entries - * @param cache whether a {@link ThreadLocal} cache should be used for the most recently released entry - * @deprecated cache is no longer supported. Use {@link StrategyType#THREAD_ID} - */ - @Deprecated - public ConcurrentPool(StrategyType strategyType, int maxSize, boolean cache) - { - this(strategyType, maxSize, pooled -> 1); - } - - /** - *

Creates an instance with the specified strategy. - * and a function that returns the max multiplex count for a given pooled object.

- * - * @param strategyType the strategy to used to lookup entries - * @param maxSize the maximum number of pooled entries - * @param cache whether a {@link ThreadLocal} cache should be used for the most recently released entry - * @param maxMultiplex a function that given the pooled object returns the max multiplex count - * @deprecated cache is no longer supported. Use {@link StrategyType#THREAD_ID} - */ - @Deprecated - public ConcurrentPool(StrategyType strategyType, int maxSize, boolean cache, ToIntFunction

maxMultiplex) - { - this(strategyType, maxSize, maxMultiplex); - } - /** *

Creates an instance with the specified strategy. * and a function that returns the max multiplex count for a given pooled object.

@@ -148,7 +118,7 @@ private void leaked(Holder

holder) { leaked.increment(); if (LOG.isDebugEnabled()) - LOG.debug("Leaked " + holder); + LOG.debug("Leaked {}", holder); leaked(); } @@ -195,15 +165,14 @@ public Entry

reserve() void sweep() { - for (int i = 0; i < entries.size(); i++) + // Remove entries atomically with respect to remove(Entry). + entries.removeIf(holder -> { - Holder

holder = entries.get(i); - if (holder.getEntry() == null) - { - entries.remove(i--); + boolean remove = holder.getEntry() == null; + if (remove) leaked(holder); - } - } + return remove; + }); } @Override @@ -285,8 +254,7 @@ private boolean remove(Entry

entry) if (!removed) return false; - // No need to lock, no race with reserve() - // and the race with terminate() is harmless. + // In a harmless race with reserve()/sweep()/terminate(). Holder

holder = ((ConcurrentEntry

)entry).getHolder(); boolean evicted = entries.remove(holder); if (LOG.isDebugEnabled()) @@ -313,10 +281,7 @@ public Collection> terminate() // Field this.terminated must be modified with the lock held // because the list of entries is modified, see reserve(). terminated = true; - copy = entries.stream() - .map(Holder::getEntry) - .filter(Objects::nonNull) - .toList(); + copy = stream().toList(); entries.clear(); } diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java index 7c21e92731d..d1658fdafd3 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java @@ -173,6 +173,21 @@ public static List asList(T[] a) return Arrays.asList(a); } + /** + *

Returns a new list with the elements of the specified list in reverse order.

+ *

The specified list is not modified, differently from {@link Collections#reverse(List)}.

+ * + * @param list the list whose elements are to be reversed + * @return a new list with the elements in reverse order + * @param the element type + */ + public static List reverse(List list) + { + List result = new ArrayList<>(list); + Collections.reverse(result); + return result; + } + /** * Class from a canonical name for a type. * diff --git a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextHandler.java b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextHandler.java index 5031b641d02..70f6ad1c02d 100644 --- a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextHandler.java +++ b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextHandler.java @@ -95,6 +95,7 @@ import org.eclipse.jetty.util.ExceptionUtil; import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; @@ -516,8 +517,7 @@ public void contextDestroyed() throws Exception //Call context listeners Throwable multiException = null; ServletContextEvent event = new ServletContextEvent(getServletContext()); - Collections.reverse(_destroyServletContextListeners); - for (ServletContextListener listener : _destroyServletContextListeners) + for (ServletContextListener listener : TypeUtil.reverse(_destroyServletContextListeners)) { try { @@ -568,17 +568,17 @@ protected void requestDestroyed(Request baseRequest, HttpServletRequest request) if (!_servletRequestListeners.isEmpty()) { final ServletRequestEvent sre = new ServletRequestEvent(getServletContext(), request); - for (int i = _servletRequestListeners.size(); i-- > 0; ) + for (ServletRequestListener listener : TypeUtil.reverse(_servletRequestListeners)) { - _servletRequestListeners.get(i).requestDestroyed(sre); + listener.requestDestroyed(sre); } } if (!_servletRequestAttributeListeners.isEmpty()) { - for (int i = _servletRequestAttributeListeners.size(); i-- > 0; ) + for (ServletRequestAttributeListener listener : TypeUtil.reverse(_servletRequestAttributeListeners)) { - scopedRequest.removeEventListener(_servletRequestAttributeListeners.get(i)); + scopedRequest.removeEventListener(listener); } } } @@ -1217,11 +1217,11 @@ protected void notifyExitScope(Request request) ServletContextRequest scopedRequest = Request.as(request, ServletContextRequest.class); if (!_contextListeners.isEmpty()) { - for (int i = _contextListeners.size(); i-- > 0; ) + for (ServletContextScopeListener listener : TypeUtil.reverse(_contextListeners)) { try { - _contextListeners.get(i).exitScope(getContext(), scopedRequest); + listener.exitScope(getContext(), scopedRequest); } catch (Throwable e) { diff --git a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/SessionHandler.java b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/SessionHandler.java index 1cf55219044..63c0f31f657 100644 --- a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/SessionHandler.java +++ b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/SessionHandler.java @@ -47,6 +47,7 @@ import org.eclipse.jetty.session.ManagedSession; import org.eclipse.jetty.session.SessionConfig; import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.TypeUtil; public class SessionHandler extends AbstractSessionManager implements Handler.Singleton { @@ -571,9 +572,9 @@ public void onSessionDestroyed(Session session) getSessionContext().run(() -> { HttpSessionEvent event = new HttpSessionEvent(session.getApi()); - for (int i = _sessionListeners.size() - 1; i >= 0; i--) + for (HttpSessionListener listener : TypeUtil.reverse(_sessionListeners)) { - _sessionListeners.get(i).sessionDestroyed(event); + listener.sessionDestroyed(event); } }); } diff --git a/jetty-ee11/jetty-ee11-servlet/src/main/java/org/eclipse/jetty/ee11/servlet/ServletContextHandler.java b/jetty-ee11/jetty-ee11-servlet/src/main/java/org/eclipse/jetty/ee11/servlet/ServletContextHandler.java index f97021240da..73ab1d4d679 100644 --- a/jetty-ee11/jetty-ee11-servlet/src/main/java/org/eclipse/jetty/ee11/servlet/ServletContextHandler.java +++ b/jetty-ee11/jetty-ee11-servlet/src/main/java/org/eclipse/jetty/ee11/servlet/ServletContextHandler.java @@ -95,6 +95,7 @@ import org.eclipse.jetty.util.ExceptionUtil; import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; @@ -515,8 +516,7 @@ public void contextDestroyed() throws Exception //Call context listeners Throwable multiException = null; ServletContextEvent event = new ServletContextEvent(getServletContext()); - Collections.reverse(_destroyServletContextListeners); - for (ServletContextListener listener : _destroyServletContextListeners) + for (ServletContextListener listener : TypeUtil.reverse(_destroyServletContextListeners)) { try { @@ -566,18 +566,18 @@ protected void requestDestroyed(Request baseRequest, HttpServletRequest request) // Handle more REALLY SILLY request events! if (!_servletRequestListeners.isEmpty()) { - final ServletRequestEvent sre = new ServletRequestEvent(getServletContext(), request); - for (int i = _servletRequestListeners.size(); i-- > 0; ) + ServletRequestEvent sre = new ServletRequestEvent(getServletContext(), request); + for (ServletRequestListener listener : TypeUtil.reverse(_servletRequestListeners)) { - _servletRequestListeners.get(i).requestDestroyed(sre); + listener.requestDestroyed(sre); } } if (!_servletRequestAttributeListeners.isEmpty()) { - for (int i = _servletRequestAttributeListeners.size(); i-- > 0; ) + for (ServletRequestAttributeListener listener : TypeUtil.reverse(_servletRequestAttributeListeners)) { - scopedRequest.removeEventListener(_servletRequestAttributeListeners.get(i)); + scopedRequest.removeEventListener(listener); } } } @@ -1217,11 +1217,11 @@ protected void notifyExitScope(Request request) ServletContextRequest scopedRequest = Request.as(request, ServletContextRequest.class); if (!_contextListeners.isEmpty()) { - for (int i = _contextListeners.size(); i-- > 0; ) + for (ServletContextScopeListener listener : TypeUtil.reverse(_contextListeners)) { try { - _contextListeners.get(i).exitScope(getContext(), scopedRequest); + listener.exitScope(getContext(), scopedRequest); } catch (Throwable e) { diff --git a/jetty-ee11/jetty-ee11-servlet/src/main/java/org/eclipse/jetty/ee11/servlet/SessionHandler.java b/jetty-ee11/jetty-ee11-servlet/src/main/java/org/eclipse/jetty/ee11/servlet/SessionHandler.java index 1507b18376f..be3bb3f68a2 100644 --- a/jetty-ee11/jetty-ee11-servlet/src/main/java/org/eclipse/jetty/ee11/servlet/SessionHandler.java +++ b/jetty-ee11/jetty-ee11-servlet/src/main/java/org/eclipse/jetty/ee11/servlet/SessionHandler.java @@ -48,6 +48,7 @@ import org.eclipse.jetty.session.ManagedSession; import org.eclipse.jetty.session.SessionConfig; import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.TypeUtil; public class SessionHandler extends AbstractSessionManager implements Handler.Singleton { @@ -615,9 +616,9 @@ public void onSessionDestroyed(Session session) getSessionContext().run(() -> { HttpSessionEvent event = new HttpSessionEvent(session.getApi()); - for (int i = _sessionListeners.size() - 1; i >= 0; i--) + for (HttpSessionListener listener : TypeUtil.reverse(_sessionListeners)) { - _sessionListeners.get(i).sessionDestroyed(event); + listener.sessionDestroyed(event); } }); } diff --git a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ContextHandler.java b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ContextHandler.java index dfe73d44112..616e8c14cca 100644 --- a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ContextHandler.java +++ b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ContextHandler.java @@ -1000,17 +1000,17 @@ protected void requestDestroyed(Request baseRequest, HttpServletRequest request) if (!_servletRequestListeners.isEmpty()) { final ServletRequestEvent sre = new ServletRequestEvent(_apiContext, request); - for (int i = _servletRequestListeners.size(); i-- > 0; ) + for (ServletRequestListener listener : TypeUtil.reverse(_servletRequestListeners)) { - _servletRequestListeners.get(i).requestDestroyed(sre); + listener.requestDestroyed(sre); } } if (!_servletRequestAttributeListeners.isEmpty()) { - for (int i = _servletRequestAttributeListeners.size(); i-- > 0; ) + for (ServletRequestAttributeListener listener : TypeUtil.reverse(_servletRequestAttributeListeners)) { - baseRequest.removeEventListener(_servletRequestAttributeListeners.get(i)); + baseRequest.removeEventListener(listener); } } } @@ -1070,11 +1070,11 @@ protected void exitScope(Request request) { if (!_contextListeners.isEmpty()) { - for (int i = _contextListeners.size(); i-- > 0; ) + for (ContextScopeListener listener : TypeUtil.reverse(_contextListeners)) { try { - _contextListeners.get(i).exitScope(_apiContext, request); + listener.exitScope(_apiContext, request); } catch (Throwable e) { diff --git a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/SessionHandler.java b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/SessionHandler.java index d77c172dc02..46f2d10a514 100644 --- a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/SessionHandler.java +++ b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/SessionHandler.java @@ -54,6 +54,7 @@ import org.eclipse.jetty.session.SessionManager; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.TypeUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -834,9 +835,9 @@ public void onSessionDestroyed(Session session) Runnable r = () -> { HttpSessionEvent event = new HttpSessionEvent(session.getApi()); - for (int i = _sessionListeners.size() - 1; i >= 0; i--) + for (HttpSessionListener listener : TypeUtil.reverse(_sessionListeners)) { - _sessionListeners.get(i).sessionDestroyed(event); + listener.sessionDestroyed(event); } }; _contextHandler.getCoreContextHandler().getContext().run(r);