1 // Copyright (c) 2016, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 
6 package org.rocksdb;
7 
8 import java.util.concurrent.atomic.AtomicBoolean;
9 
10 /**
11  * Offers functionality for implementations of
12  * {@link AbstractNativeReference} which have an immutable reference to the
13  * underlying native C++ object
14  */
15 //@ThreadSafe
16 public abstract class AbstractImmutableNativeReference
17     extends AbstractNativeReference {
18 
19   /**
20    * A flag indicating whether the current {@code AbstractNativeReference} is
21    * responsible to free the underlying C++ object
22    */
23   protected final AtomicBoolean owningHandle_;
24 
AbstractImmutableNativeReference(final boolean owningHandle)25   protected AbstractImmutableNativeReference(final boolean owningHandle) {
26     this.owningHandle_ = new AtomicBoolean(owningHandle);
27   }
28 
29   @Override
isOwningHandle()30   public boolean isOwningHandle() {
31     return owningHandle_.get();
32   }
33 
34   /**
35    * Releases this {@code AbstractNativeReference} from  the responsibility of
36    * freeing the underlying native C++ object
37    * <p>
38    * This will prevent the object from attempting to delete the underlying
39    * native object in its finalizer. This must be used when another object
40    * takes over ownership of the native object or both will attempt to delete
41    * the underlying object when garbage collected.
42    * <p>
43    * When {@code disOwnNativeHandle()} is called, {@code dispose()} will
44    * subsequently take no action. As a result, incorrect use of this function
45    * may cause a memory leak.
46    * </p>
47    *
48    * @see #dispose()
49    */
disOwnNativeHandle()50   protected final void disOwnNativeHandle() {
51     owningHandle_.set(false);
52   }
53 
54   @Override
close()55   public void close() {
56     if (owningHandle_.compareAndSet(true, false)) {
57       disposeInternal();
58     }
59   }
60 
61   /**
62    * The helper function of {@link AbstractImmutableNativeReference#dispose()}
63    * which all subclasses of {@code AbstractImmutableNativeReference} must
64    * implement to release their underlying native C++ objects.
65    */
disposeInternal()66   protected abstract void disposeInternal();
67 }
68