Skip to content

Commit acb9aa2

Browse files
committed
Fix racing on route handler's indexes change
1 parent 792bb10 commit acb9aa2

File tree

2 files changed

+44
-20
lines changed

2 files changed

+44
-20
lines changed

vertx-web/src/main/java/io/vertx/ext/web/impl/RouteState.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,16 +1279,20 @@ boolean hasNextFailureHandler(RoutingContextImplBase context) {
12791279
return context.currentRouteNextFailureHandlerIndex() < getFailureHandlersLength();
12801280
}
12811281

1282-
void handleContext(RoutingContextImplBase context) {
1283-
contextHandlers
1284-
.get(context.currentRouteNextHandlerIndex() - 1)
1285-
.handle(context);
1282+
Handler<RoutingContext> nextContextHandler(RoutingContextImplBase context) {
1283+
int index = context.nextContextHandler(getContextHandlersLength());
1284+
if (index == -1) {
1285+
return null;
1286+
}
1287+
return contextHandlers.get(index - 1);
12861288
}
12871289

1288-
void handleFailure(RoutingContextImplBase context) {
1289-
failureHandlers
1290-
.get(context.currentRouteNextFailureHandlerIndex() - 1)
1291-
.handle(context);
1290+
Handler<RoutingContext> nextFailureHandler(RoutingContextImplBase context) {
1291+
int index = context.nextFailureHandler(getFailureHandlersLength());
1292+
if (index == -1) {
1293+
return null;
1294+
}
1295+
return failureHandlers.get(index - 1);
12921296
}
12931297

12941298
public String getName() {

vertx-web/src/main/java/io/vertx/ext/web/impl/RoutingContextImplBase.java

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -130,18 +130,39 @@ void restart() {
130130
next();
131131
}
132132

133+
final int nextFailureHandler(int limit) {
134+
int index;
135+
do {
136+
index = currentRouteNextFailureHandlerIndex;
137+
if (index >= limit) {
138+
return -1;
139+
}
140+
} while (!CURRENT_ROUTE_NEXT_FAILURE_HANDLER_INDEX.compareAndSet(this, index, index + 1));
141+
return index;
142+
}
143+
144+
final int nextContextHandler(int limit) {
145+
int index;
146+
do {
147+
index = currentRouteNextHandlerIndex;
148+
if (index >= limit) {
149+
return -1;
150+
}
151+
} while (!CURRENT_ROUTE_NEXT_HANDLER_INDEX.compareAndSet(this, index, index + 1));
152+
return index;
153+
}
154+
133155
boolean iterateNext() {
134156
boolean failed = failed();
135157
if (currentRoute != null) { // Handle multiple handlers inside route object
136158
try {
137-
if (!failed && currentRoute.hasNextContextHandler(this)) {
138-
CURRENT_ROUTE_NEXT_HANDLER_INDEX.incrementAndGet(this);
159+
Handler<RoutingContext> handler;
160+
if (!failed && (handler = currentRoute.nextContextHandler(this)) != null) {
139161
resetMatchFailure();
140-
currentRoute.handleContext(this);
162+
handler.handle(this);
141163
return true;
142-
} else if (failed && currentRoute.hasNextFailureHandler(this)) {
143-
CURRENT_ROUTE_NEXT_FAILURE_HANDLER_INDEX.incrementAndGet(this);
144-
currentRoute.handleFailure(this);
164+
} else if (failed && (handler = currentRoute.nextFailureHandler(this)) != null) {
165+
handler.handle(this);
145166
return true;
146167
}
147168
} catch (Throwable t) {
@@ -169,12 +190,11 @@ boolean iterateNext() {
169190
if (LOG.isTraceEnabled()) {
170191
LOG.trace("Calling the " + (failed ? "failure" : "") + " handler");
171192
}
172-
if (failed && currentRoute.hasNextFailureHandler(this)) {
173-
CURRENT_ROUTE_NEXT_FAILURE_HANDLER_INDEX.incrementAndGet(this);
174-
routeState.handleFailure(this);
175-
} else if (currentRoute.hasNextContextHandler(this)) {
176-
CURRENT_ROUTE_NEXT_HANDLER_INDEX.incrementAndGet(this);
177-
routeState.handleContext(this);
193+
Handler<RoutingContext> handler;
194+
if (failed && (handler = currentRoute.nextFailureHandler(this)) != null) {
195+
handler.handle(this);
196+
} else if ((handler = currentRoute.nextContextHandler(this)) != null) {
197+
handler.handle(this);
178198
} else {
179199
continue;
180200
}

0 commit comments

Comments
 (0)