Skip to content

Commit

Permalink
Fix racing on route handler's indexes change
Browse files Browse the repository at this point in the history
  • Loading branch information
franz1981 committed May 6, 2024
1 parent 792bb10 commit 28ecc98
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 22 deletions.
24 changes: 14 additions & 10 deletions vertx-web/src/main/java/io/vertx/ext/web/impl/RouteState.java
Original file line number Diff line number Diff line change
Expand Up @@ -1275,20 +1275,24 @@ boolean hasNextContextHandler(RoutingContextImplBase context) {
return context.currentRouteNextHandlerIndex() < getContextHandlersLength();
}

boolean hasNextFailureHandler(RoutingContextImplBase context) {
return context.currentRouteNextFailureHandlerIndex() < getFailureHandlersLength();
Handler<RoutingContext> nextContextHandler(RoutingContextImplBase context) {
int index = context.nextContextHandler(getContextHandlersLength());
if (index == -1) {
return null;
}
return contextHandlers.get(index - 1);
}

void handleContext(RoutingContextImplBase context) {
contextHandlers
.get(context.currentRouteNextHandlerIndex() - 1)
.handle(context);
boolean hasNextFailureHandler(RoutingContextImplBase context) {
return context.currentRouteNextFailureHandlerIndex() < getFailureHandlersLength();
}

void handleFailure(RoutingContextImplBase context) {
failureHandlers
.get(context.currentRouteNextFailureHandlerIndex() - 1)
.handle(context);
Handler<RoutingContext> nextFailureHandler(RoutingContextImplBase context) {
int index = context.nextFailureHandler(getFailureHandlersLength());
if (index == -1) {
return null;
}
return failureHandlers.get(index - 1);
}

public String getName() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<RoutingContext> 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) {
Expand Down Expand Up @@ -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<RoutingContext> handler;
if (failed && (handler = currentRoute.nextFailureHandler(this)) != null) {
handler.handle(this);
} else if ((handler = currentRoute.nextContextHandler(this)) != null) {
handler.handle(this);
} else {
continue;
}
Expand Down Expand Up @@ -257,4 +277,6 @@ protected void unhandledFailure(int statusCode, Throwable failure, RouterImpl ro
private void resetMatchFailure() {
this.matchFailure = 404;
}


}

0 comments on commit 28ecc98

Please sign in to comment.