On Thu, 27 Aug 2026 17:41:03 GMT, Jaikiran Pai <[email protected]> wrote:

>> The clearest place to set readCalled is as close as possible to where read 
>> is called, so read and read0 after acquiring lock.
>
> While at it, both `in` and `decoderFromCharset` are `final` fields. I think 
> we should move the check for these fields out of the synchronized block in 
> this method. Something like (this untested code):
> 
> 
> if (in == null || !decoderFromCharset) {
>     return null;
> }
> synchronized (lock) {
>  ensureOpen();
>  if (!readCalled) {
>      return new String(in.readAllBytes(), cs);
>  }
> }
> return null;
> 
> That would prevent the necessity of acquiring the monitor on `lock` for some 
> cases.

Adopted in latest commit of this PR.

Pulling the `readCalled = true;` line up into `read()` as suggested by Alan 
implied adding `synchronized(this)` in `read()`, as seen in latest commit of 
this PR. As a side effect we now could remove `synchronized(this)` from 
`read0()` in turn, if we like, as all callers are synchronized now themselves. 
Agreed?

Also, `readCalled = true;` was needed in *more* places than just `read()` and 
`read0()`  after removing it from `readBytes()`, as there are several 
non-private entry points (like `implRead()`) that other classes could call. 
IMHO the code was simpler before (when there was just one single place that did 
`readCalled = true;`). It's up to the reviewers to decide, but my personal 
opinion is that `readCalled = true;` should not tell us whether some 
`StreamDecoder:*read*()` method was called (which is several locations), but 
solely whether `in.read()` was called (which is just a single location).

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/32264#discussion_r3881780325

Reply via email to