3434import java .util .logging .Logger ;
3535import javax .servlet .AsyncContext ;
3636import javax .servlet .ServletOutputStream ;
37- import org .checkerframework .checker .lock .qual .GuardedBy ;
3837
3938/** Handles write actions from the container thread and the application thread. */
4039final class AsyncServletOutputStreamWriter {
@@ -100,7 +99,7 @@ public void finest(String str, Object... params) {
10099 log .fine ("call completed" );
101100 });
102101 };
103- this .isReady = () -> outputStream . isReady () ;
102+ this .isReady = outputStream :: isReady ;
104103 }
105104
106105 /**
@@ -148,8 +147,7 @@ void onWritePossible() throws IOException {
148147 do {
149148 writeLock .lock ();
150149 try {
151- writeFromQueue ();
152- if (!outputKnownToBeReady ) {
150+ if (writeFromQueue () == WriteResult .OUTPUT_NOT_READY ) {
153151 log .finest ("onWritePossible: EXIT. The servlet output stream becomes not ready" );
154152 return ;
155153 }
@@ -160,26 +158,20 @@ void onWritePossible() throws IOException {
160158 log .finest ("onWritePossible: EXIT. Queue drained" );
161159 }
162160
163- @ GuardedBy ("writeLock" )
164- private boolean outputKnownToBeReady = false ;
165-
166- private void writeFromQueue () throws IOException {
167- for (;;) {
168- ActionItem actionItem ;
169- if (outputKnownToBeReady ) {
170- actionItem = writeChain .poll ();
171- } else if (isReady .getAsBoolean ()) {
172- outputKnownToBeReady = true ;
173- actionItem = writeChain .poll ();
174- } else {
175- return ;
176- }
161+ private enum WriteResult {
162+ OUTPUT_NOT_READY ,
163+ QUEUE_DRAINED
164+ }
165+
166+ private WriteResult writeFromQueue () throws IOException {
167+ while (isReady .getAsBoolean ()) {
168+ ActionItem actionItem = writeChain .poll ();
177169 if (actionItem == null ) {
178- return ;
170+ return WriteResult . QUEUE_DRAINED ;
179171 }
180172 actionItem .run ();
181- outputKnownToBeReady = false ;
182173 }
174+ return WriteResult .OUTPUT_NOT_READY ;
183175 }
184176
185177 /**
0 commit comments