Skip to content
This repository was archived by the owner on Dec 2, 2025. It is now read-only.

Commit 439103c

Browse files
committed
Make StreamingXXHash*JNI methods synchronized to avoid a race condition with GC (#131)
1 parent 9b681c8 commit 439103c

2 files changed

Lines changed: 24 additions & 9 deletions

File tree

src/java/net/jpountz/xxhash/StreamingXXHash32JNI.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,14 @@
1414
* limitations under the License.
1515
*/
1616

17-
17+
/**
18+
* Fast {@link StreamingXXHash32} implemented with JNI bindings.
19+
* The methods are synchronized to avoid a race condition
20+
* between freeing the native memory in finalize() and using it in
21+
* reset(), getValue(), and update(). Note that GC can call finalize()
22+
* after calling checkState() and before using XXHashJNI if the caller
23+
* does not retain a reference to this object.
24+
*/
1825
final class StreamingXXHash32JNI extends StreamingXXHash32 {
1926

2027
static class Factory implements StreamingXXHash32.Factory {
@@ -42,26 +49,26 @@ private void checkState() {
4249
}
4350

4451
@Override
45-
public void reset() {
52+
public synchronized void reset() {
4653
checkState();
4754
XXHashJNI.XXH32_free(state);
4855
state = XXHashJNI.XXH32_init(seed);
4956
}
5057

5158
@Override
52-
public int getValue() {
59+
public synchronized int getValue() {
5360
checkState();
5461
return XXHashJNI.XXH32_digest(state);
5562
}
5663

5764
@Override
58-
public void update(byte[] bytes, int off, int len) {
65+
public synchronized void update(byte[] bytes, int off, int len) {
5966
checkState();
6067
XXHashJNI.XXH32_update(state, bytes, off, len);
6168
}
6269

6370
@Override
64-
protected void finalize() throws Throwable {
71+
protected synchronized void finalize() throws Throwable {
6572
super.finalize();
6673
// free memory
6774
XXHashJNI.XXH32_free(state);

src/java/net/jpountz/xxhash/StreamingXXHash64JNI.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@
1515
*/
1616

1717

18+
/**
19+
* Fast {@link StreamingXXHash64} implemented with JNI bindings.
20+
* The methods are synchronized to avoid a race condition
21+
* between freeing the native memory in finalize() and using it in
22+
* reset(), getValue(), and update(). Note that GC can call finalize()
23+
* after calling checkState() and before using XXHashJNI if the caller
24+
* does not retain a reference to this object.
25+
*/
1826
final class StreamingXXHash64JNI extends StreamingXXHash64 {
1927

2028
static class Factory implements StreamingXXHash64.Factory {
@@ -42,26 +50,26 @@ private void checkState() {
4250
}
4351

4452
@Override
45-
public void reset() {
53+
public synchronized void reset() {
4654
checkState();
4755
XXHashJNI.XXH64_free(state);
4856
state = XXHashJNI.XXH64_init(seed);
4957
}
5058

5159
@Override
52-
public long getValue() {
60+
public synchronized long getValue() {
5361
checkState();
5462
return XXHashJNI.XXH64_digest(state);
5563
}
5664

5765
@Override
58-
public void update(byte[] bytes, int off, int len) {
66+
public synchronized void update(byte[] bytes, int off, int len) {
5967
checkState();
6068
XXHashJNI.XXH64_update(state, bytes, off, len);
6169
}
6270

6371
@Override
64-
protected void finalize() throws Throwable {
72+
protected synchronized void finalize() throws Throwable {
6573
super.finalize();
6674
// free memory
6775
XXHashJNI.XXH64_free(state);

0 commit comments

Comments
 (0)