mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Matthew Swift
17.24.2013 70f4956fbfdf4f2a8e92dad53d4886a318261e7a
opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/ReferenceCountedObject.java
@@ -39,7 +39,11 @@
     * released during garbage collection.
     */
    public final class Reference {
        private T value;
        /*
         * The value will be accessed by the finalizer thread so it needs to be
         * volatile in order to ensure that updates are published.
         */
        private volatile T value;
        private Reference(final T value) {
            this.value = value;
@@ -66,13 +70,23 @@
         * destroyed.
         */
        public void release() {
            releaseIfSame(value);
            T instanceToRelease = null;
            synchronized (lock) {
                if (value != null && instance == value && --refCount == 0) {
                    instanceToRelease = value;
                    instance = null;
            /*
             * Force NPE for subsequent get() attempts and prevent multiple
             * releases.
             */
            value = null;
                    /*
                     * Force NPE for subsequent get() attempts and prevent
                     * multiple releases.
                     */
                    value = null;
                }
            }
            if (instanceToRelease != null) {
                destroyInstance(instanceToRelease);
            }
        }
        /**
@@ -108,6 +122,7 @@
                assert instance == null;
                instance = newInstance();
            }
            assert instance != null;
            return new Reference(instance);
        }
    }
@@ -144,19 +159,4 @@
     */
    protected abstract T newInstance();
    private final void releaseIfSame(final T instance) {
        T instanceToRelease = null;
        synchronized (lock) {
            if (this.instance == instance) {
                if (--refCount == 0) {
                    instanceToRelease = instance;
                    this.instance = null;
                }
            }
        }
        if (instanceToRelease != null) {
            destroyInstance(instanceToRelease);
        }
    }
}