@@ -171,7 +171,7 @@ public final class SenderPool implements AutoCloseable {
171171 // down on another thread. Guarded by lock.
172172 private int pendingLeaseTeardowns ;
173173 // Slots whose delegate close() returned with the SF flock still held
174- // (the I/O thread refused to stop) . Permanently consumed: the index is
174+ // because an I/O or manager worker did not stop. Permanently consumed:
175175 // never freed and never reused, so no borrow ever hands out a still-
176176 // locked slot dir. Counted in the cap check so the lost capacity is
177177 // accounted for. Guarded by lock; only ever ticks for SF slots.
@@ -523,15 +523,15 @@ private boolean recoverOneSlotStep(long stepBudgetMillis) {
523523 // leakedSlots (retire) or the freed index carries the cap math.
524524 recoveringSlots --;
525525 if (flockHeld [0 ]) {
526- // close() bailed early with the I/O thread still running and
527- // the flock still held . Retire the slot permanently (mirror
526+ // close() retained the flock because an I/O or manager
527+ // worker did not stop . Retire the slot permanently (mirror
528528 // discardBroken/reapIdle): keep slotInUse[i] set and count it
529529 // in leakedSlots so the borrow() cap math accounts for the
530530 // lost capacity and no later borrow ever reuses the
531531 // still-locked dir.
532532 leakedSlots ++;
533533 LOG .warn ("startup SF recovery: slot {} retired permanently: delegate close() returned with "
534- + "the flock still held (I/O thread refused to stop); pool capacity reduced by 1, "
534+ + "the flock still held (I/O or manager worker did not stop); pool capacity reduced by 1, "
535535 + "now {} of {} usable [leakedSlots={}]" ,
536536 i , maxSize - leakedSlots , maxSize , leakedSlots );
537537 } else {
@@ -580,12 +580,13 @@ private boolean recoverOneSlotStep(long stepBudgetMillis) {
580580 if (flockHeld [0 ]) {
581581 // Out of the pool's [0, maxSize) capacity range: there is no
582582 // slotInUse entry to retire and no future borrow targets this
583- // dir, so a still-held flock only leaks this recoverer's I/O
584- // thread (a best-effort teardown loss, logged). Crucially we do
583+ // dir, so a still-held flock only leaks this recoverer's
584+ // worker-reachable resources (a best-effort teardown loss,
585+ // logged). Crucially we do
585586 // NOT touch leakedSlots -- that would wrongly shrink the
586587 // in-range pool capacity.
587588 LOG .warn ("startup SF recovery: out-of-range slot {} closed with the flock still held "
588- + "(I/O thread refused to stop); its data is durable on disk for a later attempt" ,
589+ + "(I/O or manager worker did not stop); its data is durable on disk for a later attempt" ,
589590 slotPath );
590591 }
591592 if (stopScan ) {
@@ -609,7 +610,7 @@ private boolean recoverOneSlotStep(long stepBudgetMillis) {
609610 *
610611 * @param flockHeld single-element out-param set to {@code true} iff a
611612 * recoverer was built and its {@code close()} returned with
612- * the flock still held (the I/O thread refused to stop)
613+ * the flock still held because a worker did not stop
613614 * @return {@code true} if a build/drain failure occurred that will very
614615 * likely repeat for every remaining slot, so the caller should stop scanning
615616 */
@@ -618,8 +619,8 @@ private boolean drainCandidateSlotForRecovery(int slotIndex, String slotPath,
618619 flockHeld [0 ] = false ;
619620 // Hoisted so the flock check after the try can consult it:
620621 // createRecoverer() takes the slot flock on <base>-slotIndex, and
621- // delegate().close() can early-return with the I/O thread still running
622- // (flock still held) .
622+ // delegate().close() can retain it when an I/O or manager worker does
623+ // not stop .
623624 SenderSlot recoverer = null ;
624625 boolean stopScan = false ;
625626 try {
@@ -1067,7 +1068,7 @@ public void reapIdle() {
10671068 }
10681069 // Return reserved SF slot indices to the free set -- but only for
10691070 // slots whose delegate confirmed the flock was released. A slot
1070- // left locked (I/O thread refused to stop) is retired permanently.
1071+ // left locked because a worker did not stop is retired permanently.
10711072 if (storeAndForward ) {
10721073 lock .lock ();
10731074 try {
@@ -1107,8 +1108,8 @@ public int totalSize() {
11071108
11081109 /**
11091110 * Snapshot of the number of SF slots permanently retired because a
1110- * delegate {@code close()} returned with the slot flock still held (the
1111- * I/O thread refused to stop) . Each leaked slot permanently lowers the
1111+ * delegate {@code close()} returned with the slot flock still held after
1112+ * an I/O or manager worker did not stop. Each leaked slot permanently lowers the
11121113 * pool's effective capacity ({@code maxSize - leakedSlotCount()}). A
11131114 * non-zero, growing value explains a pool that has started timing out
11141115 * every {@code borrow()}. For metrics and tests.
@@ -1271,7 +1272,7 @@ private void freeSlotIndex(int idx) {
12711272 * non-QWP delegate never holds an SF flock, so it is always treated as
12721273 * released. A {@link QwpWebSocketSender} reports it via
12731274 * {@link QwpWebSocketSender#isSlotLockReleased()} -- false means close()
1274- * bailed early with the I/O thread still running and the flock still held .
1275+ * retained the flock because an I/O or manager worker did not stop .
12751276 */
12761277 private static boolean flockReleased (SenderSlot s ) {
12771278 Sender d = s .delegate ();
@@ -1281,8 +1282,8 @@ private static boolean flockReleased(SenderSlot s) {
12811282 /**
12821283 * Reclaims one SF slot after its delegate's {@code close()} has been
12831284 * attempted. When the flock was released the index returns to the free
1284- * set; when {@code close()} returned with the flock still held (the I/O
1285- * thread refused to stop) the slot is retired permanently --
1285+ * set; when {@code close()} returned with the flock still held because an
1286+ * I/O or manager worker did not stop, the slot is retired permanently --
12861287 * {@code leakedSlots++} and {@code slotInUse[idx]} stays set -- so the cap
12871288 * math accounts for the lost capacity and no later borrow ever reuses the
12881289 * still-locked dir. Either way {@code closingSlots} is decremented.
@@ -1304,7 +1305,7 @@ private boolean reclaimSlot(SenderSlot s, String context) {
13041305 }
13051306 leakedSlots ++;
13061307 LOG .warn ("SF slot {} retired permanently{}: delegate close() returned with the flock still held " +
1307- "(I/O thread refused to stop); pool capacity reduced by 1, now {} of {} usable [leakedSlots={}]" ,
1308+ "(I/O or manager worker did not stop); pool capacity reduced by 1, now {} of {} usable [leakedSlots={}]" ,
13081309 s .slotIndex (), context , maxSize - leakedSlots , maxSize , leakedSlots );
13091310 return false ;
13101311 }
0 commit comments