Make all BrotliOutputStream methods exclusive/blocking. If access is naturally exclusive, then it is nearly zero-cost (1 atomic CAS) PiperOrigin-RevId: 844769720
diff --git a/java/org/brotli/wrapper/enc/BrotliOutputStream.java b/java/org/brotli/wrapper/enc/BrotliOutputStream.java index 10595d1..fe3596d 100644 --- a/java/org/brotli/wrapper/enc/BrotliOutputStream.java +++ b/java/org/brotli/wrapper/enc/BrotliOutputStream.java
@@ -18,6 +18,7 @@ /** The default internal buffer size used by the encoder. */ private static final int DEFAULT_BUFFER_SIZE = 16384; + private final Object lock = new Object(); private final Encoder encoder; /** @@ -42,31 +43,39 @@ } public void attachDictionary(PreparedDictionary dictionary) throws IOException { - encoder.attachDictionary(dictionary); + synchronized (lock) { + encoder.attachDictionary(dictionary); + } } @Override public void close() throws IOException { - encoder.close(); + synchronized (lock) { + encoder.close(); + } } @Override public void flush() throws IOException { - if (encoder.closed) { - throw new IOException("write after close"); + synchronized (lock) { + if (encoder.closed) { + throw new IOException("write after close"); + } + encoder.flush(); } - encoder.flush(); } @Override public void write(int b) throws IOException { - if (encoder.closed) { - throw new IOException("write after close"); + synchronized (lock) { + if (encoder.closed) { + throw new IOException("write after close"); + } + while (!encoder.encode(EncoderJNI.Operation.PROCESS)) { + // Busy-wait loop. + } + encoder.inputBuffer.put((byte) b); } - while (!encoder.encode(EncoderJNI.Operation.PROCESS)) { - // Busy-wait loop. - } - encoder.inputBuffer.put((byte) b); } @Override @@ -76,17 +85,19 @@ @Override public void write(byte[] b, int off, int len) throws IOException { - if (encoder.closed) { - throw new IOException("write after close"); - } - while (len > 0) { - if (!encoder.encode(EncoderJNI.Operation.PROCESS)) { - continue; + synchronized (lock) { + if (encoder.closed) { + throw new IOException("write after close"); } - int limit = Math.min(len, encoder.inputBuffer.remaining()); - encoder.inputBuffer.put(b, off, limit); - off += limit; - len -= limit; + while (len > 0) { + if (!encoder.encode(EncoderJNI.Operation.PROCESS)) { + continue; + } + int limit = Math.min(len, encoder.inputBuffer.remaining()); + encoder.inputBuffer.put(b, off, limit); + off += limit; + len -= limit; + } } } }