parent
c5af85ecad
commit
0f2fdfe23a
@ -0,0 +1,66 @@ |
|||||||
|
// Copyright (c) 2016, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under the BSD-style license found in the
|
||||||
|
// LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
// of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
|
||||||
|
package org.rocksdb; |
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean; |
||||||
|
|
||||||
|
/** |
||||||
|
* Offers functionality for implementations of |
||||||
|
* {@link AbstractNativeReference} which have an immutable reference to the |
||||||
|
* underlying native C++ object |
||||||
|
*/ |
||||||
|
public abstract class AbstractImmutableNativeReference |
||||||
|
extends AbstractNativeReference { |
||||||
|
|
||||||
|
/** |
||||||
|
* A flag indicating whether the current {@code AbstractNativeReference} is |
||||||
|
* responsible to free the underlying C++ object |
||||||
|
*/ |
||||||
|
private final AtomicBoolean owningHandle_; |
||||||
|
|
||||||
|
protected AbstractImmutableNativeReference(final boolean owningHandle) { |
||||||
|
this.owningHandle_ = new AtomicBoolean(owningHandle); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isOwningHandle() { |
||||||
|
return owningHandle_.get(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Releases this {@code AbstractNativeReference} from the responsibility of |
||||||
|
* freeing the underlying native C++ object |
||||||
|
* <p> |
||||||
|
* This will prevent the object from attempting to delete the underlying |
||||||
|
* native object in its finalizer. This must be used when another object |
||||||
|
* takes over ownership of the native object or both will attempt to delete |
||||||
|
* the underlying object when garbage collected. |
||||||
|
* <p> |
||||||
|
* When {@code disOwnNativeHandle()} is called, {@code dispose()} will |
||||||
|
* subsequently take no action. As a result, incorrect use of this function |
||||||
|
* may cause a memory leak. |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @see #dispose() |
||||||
|
*/ |
||||||
|
protected final void disOwnNativeHandle() { |
||||||
|
owningHandle_.set(false); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public final void dispose() { |
||||||
|
if (owningHandle_.compareAndSet(true, false)) { |
||||||
|
disposeInternal(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* The helper function of {@link AbstractImmutableNativeReference#dispose()} |
||||||
|
* which all subclasses of {@code AbstractImmutableNativeReference} must |
||||||
|
* implement to release their underlying native C++ objects. |
||||||
|
*/ |
||||||
|
protected abstract void disposeInternal(); |
||||||
|
} |
@ -0,0 +1,57 @@ |
|||||||
|
// Copyright (c) 2016, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under the BSD-style license found in the
|
||||||
|
// LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
// of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
|
||||||
|
package org.rocksdb; |
||||||
|
|
||||||
|
/** |
||||||
|
* AbstractNativeReference is the base-class of all RocksDB classes that have |
||||||
|
* a pointer to a native C++ {@code rocksdb} object. |
||||||
|
* <p> |
||||||
|
* AbstractNativeReference has the {@link AbstractNativeReference#dispose()} |
||||||
|
* method, which frees its associated C++ object.</p> |
||||||
|
* <p> |
||||||
|
* This function should be called manually, however, if required it will be |
||||||
|
* called automatically during the regular Java GC process via |
||||||
|
* {@link AbstractNativeReference#finalize()}.</p> |
||||||
|
* <p> |
||||||
|
* Note - Java can only see the long member variable (which is the C++ pointer |
||||||
|
* value to the native object), as such it does not know the real size of the |
||||||
|
* object and therefore may assign a low GC priority for it; So it is strongly |
||||||
|
* suggested that you manually dispose of objects when you are finished with |
||||||
|
* them.</p> |
||||||
|
*/ |
||||||
|
public abstract class AbstractNativeReference { |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns true if we are responsible for freeing the underlying C++ object |
||||||
|
* |
||||||
|
* @return true if we are responsible to free the C++ object |
||||||
|
* @see #dispose() |
||||||
|
*/ |
||||||
|
protected abstract boolean isOwningHandle(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Frees the underlying C++ object |
||||||
|
* <p> |
||||||
|
* It is strong recommended that the developer calls this after they |
||||||
|
* have finished using the object.</p> |
||||||
|
* <p> |
||||||
|
* Note, that once an instance of {@link AbstractNativeReference} has been |
||||||
|
* disposed, calling any of its functions will lead to undefined |
||||||
|
* behavior.</p> |
||||||
|
*/ |
||||||
|
public abstract void dispose(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Simply calls {@link AbstractNativeReference#dispose()} to free |
||||||
|
* any underlying C++ object reference which has not yet been manually |
||||||
|
* released. |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
protected void finalize() throws Throwable { |
||||||
|
dispose(); |
||||||
|
super.finalize(); |
||||||
|
} |
||||||
|
} |
@ -1,77 +0,0 @@ |
|||||||
package org.rocksdb; |
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean; |
|
||||||
|
|
||||||
public abstract class NativeReference { |
|
||||||
|
|
||||||
/** |
|
||||||
* A flag indicating whether the current {@code RocksObject} is responsible to |
|
||||||
* release the c++ object stored in its {@code nativeHandle_}. |
|
||||||
*/ |
|
||||||
private final AtomicBoolean owningHandle_; |
|
||||||
|
|
||||||
protected NativeReference(final boolean owningHandle) { |
|
||||||
this.owningHandle_ = new AtomicBoolean(owningHandle); |
|
||||||
} |
|
||||||
|
|
||||||
public boolean isOwningHandle() { |
|
||||||
return owningHandle_.get(); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Revoke ownership of the native object. |
|
||||||
* <p> |
|
||||||
* This will prevent the object from attempting to delete the underlying |
|
||||||
* native object in its finalizer. This must be used when another object |
|
||||||
* takes over ownership of the native object or both will attempt to delete |
|
||||||
* the underlying object when garbage collected. |
|
||||||
* <p> |
|
||||||
* When {@code disOwnNativeHandle()} is called, {@code dispose()} will simply set |
|
||||||
* {@code nativeHandle_} to 0 without releasing its associated C++ resource. |
|
||||||
* As a result, incorrectly use this function may cause memory leak, and this |
|
||||||
* function call will not affect the return value of {@code isInitialized()}. |
|
||||||
* </p> |
|
||||||
* @see #dispose() |
|
||||||
*/ |
|
||||||
protected final void disOwnNativeHandle() { |
|
||||||
owningHandle_.set(false); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Release the c++ object manually pointed by the native handle. |
|
||||||
* <p> |
|
||||||
* Note that {@code dispose()} will also be called during the GC process |
|
||||||
* if it was not called before its {@code RocksObject} went out-of-scope. |
|
||||||
* However, since Java may wrongly wrongly assume those objects are |
|
||||||
* small in that they seems to only hold a long variable. As a result, |
|
||||||
* they might have low priority in the GC process. To prevent this, |
|
||||||
* it is suggested to call {@code dispose()} manually. |
|
||||||
* </p> |
|
||||||
* <p> |
|
||||||
* Note that once an instance of {@code RocksObject} has been disposed, |
|
||||||
* calling its function will lead undefined behavior. |
|
||||||
* </p> |
|
||||||
*/ |
|
||||||
public final void dispose() { |
|
||||||
if (owningHandle_.compareAndSet(true, false)) { |
|
||||||
disposeInternal(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* The helper function of {@code dispose()} which all subclasses of |
|
||||||
* {@code RocksObject} must implement to release their associated |
|
||||||
* C++ resource. |
|
||||||
*/ |
|
||||||
protected abstract void disposeInternal(); |
|
||||||
|
|
||||||
/** |
|
||||||
* Simply calls {@code dispose()} and release its c++ resource if it has not |
|
||||||
* yet released. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
protected void finalize() throws Throwable { |
|
||||||
dispose(); |
|
||||||
super.finalize(); |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue