From 56ef2caaa5ebfe855a4b8d76eec4d33cf04e731d Mon Sep 17 00:00:00 2001 From: fyrz Date: Mon, 27 Oct 2014 20:55:57 +0100 Subject: [PATCH] [RocksJava] - Hardening RocksIterator RocksIterator will sometimes Sigsegv on dispose. Mainly thats related to dispose order. If the related RocksDB instance is freed beforehand RocksIterator.dispose() will fail. Within this commit there is a major change to RocksIterator. RocksIterator will hold a private reference to the RocksDB instance which created the RocksIterator. So even if RocksDB is freed in the same GC cycle the RocksIterator instances will be freed prior to related RocksDB instances. Another aspect targets the dispose logic if the RocksDB is freed previously and already gc`ed. On dispose of a RocksIterator the dispose logic will check if the RocksDB instance points to an initialized DB. If not the dispose logic will not perform any further action. The crash can be reproduced by using the related test provided within this commit. Related information: This relates to @adamretter`s facebook rocksdb-dev group post about SigSegv on RocksIterator.dispose(). --- java/Makefile | 1 + java/org/rocksdb/RocksDB.java | 7 +-- java/org/rocksdb/RocksIterator.java | 9 +++- java/org/rocksdb/test/RocksIteratorTest.java | 48 ++++++++++++++++++++ 4 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 java/org/rocksdb/test/RocksIteratorTest.java diff --git a/java/Makefile b/java/Makefile index d490da4e5..8c147f9b4 100644 --- a/java/Makefile +++ b/java/Makefile @@ -46,6 +46,7 @@ test: java java -ea -Djava.library.path=.:../ -cp "$(ROCKSDB_JAR):.:./*" org.rocksdb.test.OptionsTest java -ea -Djava.library.path=.:../ -cp "$(ROCKSDB_JAR):.:./*" org.rocksdb.test.ReadOnlyTest java -ea -Djava.library.path=.:../ -cp "$(ROCKSDB_JAR):.:./*" org.rocksdb.test.ReadOptionsTest + java -ea -Djava.library.path=.:../ -cp "$(ROCKSDB_JAR):.:./*" org.rocksdb.test.RocksIteratorTest java -ea -Djava.library.path=.:../ -cp "$(ROCKSDB_JAR):.:./*" org.rocksdb.test.SnapshotTest java -ea -Djava.library.path=.:../ -cp "$(ROCKSDB_JAR):.:./*" org.rocksdb.test.StatisticsCollectorTest java -ea -Djava.library.path=.:../ -cp "$(ROCKSDB_JAR):.:./*" org.rocksdb.test.ComparatorOptionsTest diff --git a/java/org/rocksdb/RocksDB.java b/java/org/rocksdb/RocksDB.java index 676f636d4..ca26a596d 100644 --- a/java/org/rocksdb/RocksDB.java +++ b/java/org/rocksdb/RocksDB.java @@ -888,7 +888,7 @@ public class RocksDB extends RocksObject { * @return instance of iterator object. */ public RocksIterator newIterator() { - return new RocksIterator(iterator0(nativeHandle_)); + return new RocksIterator(this, iterator0(nativeHandle_)); } @@ -936,7 +936,8 @@ public class RocksDB extends RocksObject { * @return instance of iterator object. */ public RocksIterator newIterator(ColumnFamilyHandle columnFamilyHandle) { - return new RocksIterator(iterator0(nativeHandle_, columnFamilyHandle.nativeHandle_)); + return new RocksIterator(this, iterator0(nativeHandle_, + columnFamilyHandle.nativeHandle_)); } /** @@ -958,7 +959,7 @@ public class RocksDB extends RocksObject { long[] iteratorRefs = iterators(nativeHandle_, columnFamilyHandleList); for (int i=0; i