Thanks guys, fixed at r820776. Regards, Tim
On 01/Oct/2009 18:11, Oliver Deakin wrote: > Tim Ellison wrote: >> Could somebody please take a look a the patch below and see if they >> believe my explanation for why it fixes a findbugs problem in >> InputStream? >> >> The problem: We have a static, skipBuf, that we only use to read junk >> data from the stream when skipping a number of bytes. The static is >> lazily initialized. It may be null, or too small for the job. The >> problem is that another thread could also see null (or a small buffer) >> and then set the buffer too small after the calling thread sets it to >> /their/ required size. >> >> The solution: If we take a local copy, localBuf, as a snapshot of >> skipBuf before testing it, then even if the skipBuf value is slammed by >> another thread we have our local copy. We can also blindly overwrite >> any value stored by other threads since they will be doing the same >> thing. >> >> So the update of the static is still unsafe, but the usage of it is ok >> -- and this is better than making it volatile. >> >> Agree? >> > > +1 from me. > > Regards, > Oliver > >> Tim >> >> >> Index: InputStream.java >> =================================================================== >> --- InputStream.java (revision 820251) >> +++ InputStream.java (working copy) >> @@ -211,11 +211,16 @@ >> } >> long skipped = 0; >> int toRead = n < 4096 ? (int) n : 4096; >> - if (skipBuf == null || skipBuf.length < toRead) { >> - skipBuf = new byte[toRead]; >> + // We are unsynchronized, so take a local copy of the skipBuf >> at some >> + // point in time. >> + byte[] localBuf = skipBuf; >> + if (localBuf == null || localBuf.length < toRead) { >> + // May be lazily written back to the static. No matter if it >> + // overwrites somebody else's store. >> + skipBuf = localBuf = new byte[toRead]; >> } >> while (skipped < n) { >> - int read = read(skipBuf, 0, toRead); >> + int read = read(localBuf, 0, toRead); >> if (read == -1) { >> return skipped; >> } >> >> >> >