Commit 6895f57
committed
PAYG: synchronize spilled/spillStream reads in flush/close (Aikido)
flush() and close() on TeeingServletOutputStream read `spilled` and
`spillStream` while the writers (recordSingleByte, recordRange,
spillToDisk) mutate them under `synchronized(PaygResponseBodyWrapper.this)`.
Without matching synchronization on the read side, the JMM permits a
stale-false `spilled` or a partially-published `spillStream`, which would
manifest as a lost final flush or an NPE.
In practice Tomcat's HTTP/1.1 connector dispatches a single request on
one thread, but the wrapper is documented to outlive the dispatch thread
(it survives into AsyncListener.onComplete on a container thread), so the
cross-thread happens-before is real.
Fix matches the existing writer pattern by reading under the outer
PaygResponseBodyWrapper.this monitor.
Caught by Aikido AI on #6519.1 parent 8e66678 commit 6895f57
1 file changed
Lines changed: 14 additions & 4 deletions
Lines changed: 14 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
213 | 213 | | |
214 | 214 | | |
215 | 215 | | |
216 | | - | |
217 | | - | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
218 | 226 | | |
219 | 227 | | |
220 | 228 | | |
221 | 229 | | |
222 | 230 | | |
223 | 231 | | |
224 | | - | |
225 | | - | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
226 | 236 | | |
227 | 237 | | |
228 | 238 | | |
| |||
0 commit comments