@@ -217,7 +217,11 @@ private void assureReadyAndDrainedTurnsFalse() {
217217 */
218218 private void runOrBuffer (ActionItem actionItem ) throws IOException {
219219 WriteState curState = writeState .get ();
220- if (curState .readyAndDrained ) { // write to the outputStream directly
220+
221+ // Evaluate Tomcat's actual state alongside our cached state
222+ boolean actualReady = curState .readyAndDrained && isReady .getAsBoolean ();
223+
224+ if (actualReady ) { // write to the outputStream directly
221225 actionItem .run ();
222226 if (actionItem == completeAction ) {
223227 return ;
@@ -232,13 +236,21 @@ private void runOrBuffer(ActionItem actionItem) throws IOException {
232236 } else { // buffer to the writeChain
233237 writeChain .offer (actionItem );
234238 if (!writeState .compareAndSet (curState , curState .withReadyAndDrained (false ))) {
235- checkState (
236- writeState .get ().readyAndDrained ,
237- "Bug: onWritePossible() should have changed readyAndDrained to true, but not" );
238- ActionItem lastItem = writeChain .poll ();
239- if (lastItem != null ) {
240- checkState (lastItem == actionItem , "Bug: lastItem != actionItem" );
241- runOrBuffer (lastItem );
239+ // STATE CHANGED! Determine why the CAS failed based on our initial state.
240+ if (curState .readyAndDrained ) {
241+ // We dropped here solely because isReady() was false.
242+ // CAS failed because another concurrent thread already CAS'd it to false.
243+ // This is completely safe. Tomcat will call onWritePossible(). Do nothing.
244+ } else {
245+ // Original logic: We started as false, CAS failed because onWritePossible set it to true.
246+ checkState (
247+ writeState .get ().readyAndDrained ,
248+ "Bug: onWritePossible() should have changed readyAndDrained to true, but not" );
249+ ActionItem lastItem = writeChain .poll ();
250+ if (lastItem != null ) {
251+ checkState (lastItem == actionItem , "Bug: lastItem != actionItem" );
252+ runOrBuffer (lastItem );
253+ }
242254 }
243255 } // state has not changed since
244256 }
0 commit comments