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 acb9aa2
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 20 deletions.
20 changes: 12 additions & 8 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 @@ -1279,16 +1279,20 @@ boolean hasNextFailureHandler(RoutingContextImplBase context) {
return context.currentRouteNextFailureHandlerIndex() < getFailureHandlersLength();
}

void handleContext(RoutingContextImplBase context) {
contextHandlers
.get(context.currentRouteNextHandlerIndex() - 1)
.handle(context);
Handler<RoutingContext> nextContextHandler(RoutingContextImplBase context) {
int index = context.nextContextHandler(getContextHandlersLength());
if (index == -1) {
return null;
}
return contextHandlers.get(index - 1);
}

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

0 comments on commit acb9aa2

Please sign in to comment.