diff --git a/vertx-web/src/main/java/io/vertx/ext/web/impl/RouteState.java b/vertx-web/src/main/java/io/vertx/ext/web/impl/RouteState.java index 9221b2ab7c..106f680cb8 100644 --- a/vertx-web/src/main/java/io/vertx/ext/web/impl/RouteState.java +++ b/vertx-web/src/main/java/io/vertx/ext/web/impl/RouteState.java @@ -1279,16 +1279,20 @@ boolean hasNextFailureHandler(RoutingContextImplBase context) { return context.currentRouteNextFailureHandlerIndex() < getFailureHandlersLength(); } - void handleContext(RoutingContextImplBase context) { - contextHandlers - .get(context.currentRouteNextHandlerIndex() - 1) - .handle(context); + Handler nextContextHandler(RoutingContextImplBase context) { + int index = context.nextContextHandler(getContextHandlersLength()); + if (index < 0) { + return null; + } + return contextHandlers.get(index); } - void handleFailure(RoutingContextImplBase context) { - failureHandlers - .get(context.currentRouteNextFailureHandlerIndex() - 1) - .handle(context); + Handler nextFailureHandler(RoutingContextImplBase context) { + int index = context.nextFailureHandler(getFailureHandlersLength()); + if (index < 0) { + return null; + } + return failureHandlers.get(index); } public String getName() { diff --git a/vertx-web/src/main/java/io/vertx/ext/web/impl/RoutingContextImplBase.java b/vertx-web/src/main/java/io/vertx/ext/web/impl/RoutingContextImplBase.java index 1e9860d956..65c88c9944 100644 --- a/vertx-web/src/main/java/io/vertx/ext/web/impl/RoutingContextImplBase.java +++ b/vertx-web/src/main/java/io/vertx/ext/web/impl/RoutingContextImplBase.java @@ -130,18 +130,39 @@ void restart() { next(); } + final int nextFailureHandler(int limit) { + int index; + do { + index = currentRouteNextFailureHandlerIndex; + if (index >= limit) { + return -1; + } + } while (!CURRENT_ROUTE_NEXT_FAILURE_HANDLER_INDEX.compareAndSet(this, index, index + 1)); + return index; + } + + final int nextContextHandler(int limit) { + int index; + do { + index = currentRouteNextHandlerIndex; + if (index >= limit) { + return -1; + } + } while (!CURRENT_ROUTE_NEXT_HANDLER_INDEX.compareAndSet(this, index, index + 1)); + return index; + } + boolean iterateNext() { boolean failed = failed(); if (currentRoute != null) { // Handle multiple handlers inside route object try { - if (!failed && currentRoute.hasNextContextHandler(this)) { - CURRENT_ROUTE_NEXT_HANDLER_INDEX.incrementAndGet(this); + Handler handler; + if (!failed && (handler = currentRoute.nextContextHandler(this)) != null) { resetMatchFailure(); - currentRoute.handleContext(this); + handler.handle(this); return true; - } else if (failed && currentRoute.hasNextFailureHandler(this)) { - CURRENT_ROUTE_NEXT_FAILURE_HANDLER_INDEX.incrementAndGet(this); - currentRoute.handleFailure(this); + } else if (failed && (handler = currentRoute.nextFailureHandler(this)) != null) { + handler.handle(this); return true; } } catch (Throwable t) { @@ -169,12 +190,11 @@ boolean iterateNext() { if (LOG.isTraceEnabled()) { LOG.trace("Calling the " + (failed ? "failure" : "") + " handler"); } - if (failed && currentRoute.hasNextFailureHandler(this)) { - CURRENT_ROUTE_NEXT_FAILURE_HANDLER_INDEX.incrementAndGet(this); - routeState.handleFailure(this); - } else if (currentRoute.hasNextContextHandler(this)) { - CURRENT_ROUTE_NEXT_HANDLER_INDEX.incrementAndGet(this); - routeState.handleContext(this); + Handler handler; + if (failed && (handler = currentRoute.nextFailureHandler(this)) != null) { + handler.handle(this); + } else if ((handler = currentRoute.nextContextHandler(this)) != null) { + handler.handle(this); } else { continue; }