Merge pull request #153 from bpot/fix_jni_segfault

Segfault when using BackupableDB with Java bindings
This commit is contained in:
Yueh-Hsuan Chiang 2014-05-27 14:07:22 -07:00
commit 663627abf3
2 changed files with 21 additions and 9 deletions

View File

@ -25,11 +25,14 @@ public class BackupableDB extends RocksDB {
public static BackupableDB open( public static BackupableDB open(
Options opt, BackupableDBOptions bopt, String db_path) Options opt, BackupableDBOptions bopt, String db_path)
throws RocksDBException { throws RocksDBException {
// since BackupableDB c++ will handle the life cycle of
// the returned RocksDB of RocksDB.open(), here we store RocksDB db = RocksDB.open(opt, db_path);
// it as a BackupableDB member variable to avoid GC. BackupableDB bdb = new BackupableDB();
BackupableDB bdb = new BackupableDB(RocksDB.open(opt, db_path)); bdb.open(db.nativeHandle_, bopt.nativeHandle_);
bdb.open(bdb.db_.nativeHandle_, bopt.nativeHandle_);
// Prevent the RocksDB object from attempting to delete
// the underly C++ DB object.
db.disOwnNativeObject();
return bdb; return bdb;
} }
@ -64,9 +67,8 @@ public class BackupableDB extends RocksDB {
* A protected construction that will be used in the static factory * A protected construction that will be used in the static factory
* method BackupableDB.open(). * method BackupableDB.open().
*/ */
protected BackupableDB(RocksDB db) { protected BackupableDB() {
super(); super();
db_ = db;
} }
@Override protected void finalize() { @Override protected void finalize() {
@ -75,6 +77,4 @@ public class BackupableDB extends RocksDB {
protected native void open(long rocksDBHandle, long backupDBOptionsHandle); protected native void open(long rocksDBHandle, long backupDBOptionsHandle);
protected native void createNewBackup(long handle, boolean flag); protected native void createNewBackup(long handle, boolean flag);
private final RocksDB db_;
} }

View File

@ -337,6 +337,18 @@ public class RocksDB extends RocksObject {
opt.filter_ = null; 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 // native methods
protected native void open( protected native void open(
long optionsHandle, long cacheSize, String path) throws RocksDBException; long optionsHandle, long cacheSize, String path) throws RocksDBException;