From 70f4956fbfdf4f2a8e92dad53d4886a318261e7a Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Mon, 17 Jun 2013 17:24:19 +0000
Subject: [PATCH] Attempt to fix OPENDJ-994: Occasional NPEs in SDK unit tests

---
 opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/ReferenceCountedObject.java |   44 ++++++++++++++++++++++----------------------
 1 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/ReferenceCountedObject.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/ReferenceCountedObject.java
index 0bdd3e7..95457c5 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/ReferenceCountedObject.java
+++ b/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);
-        }
-    }
-
 }

--
Gitblit v1.10.0