From 5fe176d8f61ded795a9d26f94f25c65f274dd220 Mon Sep 17 00:00:00 2001 From: Bob Potter Date: Tue, 20 May 2014 18:52:27 -0500 Subject: [PATCH 1/2] Java Bindings: prevent segfault from double delete Give BackupableDB sole responsibility of the native object to prevent RocksDB from also trying to delete it. --- java/org/rocksdb/BackupableDB.java | 4 ++++ java/org/rocksdb/RocksDB.java | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/java/org/rocksdb/BackupableDB.java b/java/org/rocksdb/BackupableDB.java index 91607d4df..b85f792fc 100644 --- a/java/org/rocksdb/BackupableDB.java +++ b/java/org/rocksdb/BackupableDB.java @@ -31,6 +31,10 @@ public class BackupableDB extends RocksDB { BackupableDB bdb = new BackupableDB(RocksDB.open(opt, db_path)); bdb.open(bdb.db_.nativeHandle_, bopt.nativeHandle_); + // Prevent the RocksDB object from attempting to delete + // the underly C++ DB object. + bdb.db_.disOwnNativeObject(); + return bdb; } diff --git a/java/org/rocksdb/RocksDB.java b/java/org/rocksdb/RocksDB.java index 23dad1dc4..bc0390d9f 100644 --- a/java/org/rocksdb/RocksDB.java +++ b/java/org/rocksdb/RocksDB.java @@ -337,6 +337,18 @@ public class RocksDB extends RocksObject { opt.filter_ = null; } + /** + * Revoke ownership of the native object. + * + * This will prevent the object from attempting to delete the underlying + * native object in its finalizer. This must be used when another object + * (e.g. BackupableDB) takes over ownership of the native object or both + * will attempt to delete the underlying object when garbage collected. + */ + protected void disOwnNativeObject() { + nativeHandle_ = 0; + } + // native methods protected native void open( long optionsHandle, long cacheSize, String path) throws RocksDBException; From 05dd018353aeb9448ccd02fb954389cb28090086 Mon Sep 17 00:00:00 2001 From: Bob Potter Date: Tue, 27 May 2014 13:54:02 -0500 Subject: [PATCH 2/2] BackupableDB: don't keep a reference to the RocksDB object now that we have disOwnNativeObject --- java/org/rocksdb/BackupableDB.java | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/java/org/rocksdb/BackupableDB.java b/java/org/rocksdb/BackupableDB.java index b85f792fc..f57d47df1 100644 --- a/java/org/rocksdb/BackupableDB.java +++ b/java/org/rocksdb/BackupableDB.java @@ -25,15 +25,14 @@ public class BackupableDB extends RocksDB { public static BackupableDB open( Options opt, BackupableDBOptions bopt, String db_path) throws RocksDBException { - // since BackupableDB c++ will handle the life cycle of - // the returned RocksDB of RocksDB.open(), here we store - // it as a BackupableDB member variable to avoid GC. - BackupableDB bdb = new BackupableDB(RocksDB.open(opt, db_path)); - bdb.open(bdb.db_.nativeHandle_, bopt.nativeHandle_); + + RocksDB db = RocksDB.open(opt, db_path); + BackupableDB bdb = new BackupableDB(); + bdb.open(db.nativeHandle_, bopt.nativeHandle_); // Prevent the RocksDB object from attempting to delete // the underly C++ DB object. - bdb.db_.disOwnNativeObject(); + db.disOwnNativeObject(); return bdb; } @@ -68,9 +67,8 @@ public class BackupableDB extends RocksDB { * A protected construction that will be used in the static factory * method BackupableDB.open(). */ - protected BackupableDB(RocksDB db) { + protected BackupableDB() { super(); - db_ = db; } @Override protected void finalize() { @@ -79,6 +77,4 @@ public class BackupableDB extends RocksDB { protected native void open(long rocksDBHandle, long backupDBOptionsHandle); protected native void createNewBackup(long handle, boolean flag); - - private final RocksDB db_; }