gnodet-bot commented on code in PR #26624:
URL: https://github.com/apache/camel/pull/26624#discussion_r4056689805


##########
components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpComponent.java:
##########
@@ -254,6 +258,16 @@ protected void doStop() throws Exception {
     }
 
     public Vertx getVertx() {
+        if (vertx == null && (isNew() || isInit() || isStarting() || 
isStarted())) {

Review Comment:
   ⚠️ **TOCTOU gap — Vert.x resource leak under concurrent stop/getVertx**
   
   The lifecycle-state guard (`isNew() || isInit() || isStarting() || 
isStarted()`) is evaluated **outside** `synchronized(this)`. 
`BaseService.stop()` transitions state under a separate `ReentrantLock` — the 
two monitors are entirely independent and do not exclude each other.
   
   Concrete race:
   1. Thread A enters `getVertx()`: reads `vertx == null` ✓, reads 
`isStarted()` = true ✓ — outer check passes.
   2. Thread B calls `stop()`: acquires `BaseService.lock`, sets `status = 
STOPPING`, calls `doStop()`.
   3. `doStop()` evaluates `managedVertx && vertx != null` — `vertx` is still 
null → skips `close()`, writes `vertx = null` (no-op), sets `status = STOPPED`.
   4. Thread A enters `synchronized(this)`: `vertx == null` — still true → 
calls `createManagedVertx()`, sets `vertx = new Vert.x instance`, `managedVertx 
= true`.
   5. `doStop()` already ran and will **never run again**. The new Vert.x is 
never closed → **resource leak**.
   
   The fix is to re-check the lifecycle guard inside the synchronized block, so 
that a thread that lost the race to `stop()` does not create an unmanaged 
instance:
   
   ```suggestion
           if (vertx == null && (isNew() || isInit() || isStarting() || 
isStarted())) {
               // an endpoint can start before this component: a component 
resolved while the routes start (the
               // rest-openapi producer picks its HTTP client at that point) is 
built and initialized but not started,
               // and its endpoint then found no Vert.x (CAMEL-24822); the 
managed instance is created on first use
               synchronized (this) {
                   if (vertx == null && (isNew() || isInit() || isStarting() || 
isStarted())) {
                       createManagedVertx();
                   }
               }
           }
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to