BUG-4202: ForeignShardModificationContext should check readiness 44/34644/3
authorRobert Varga <rovarga@cisco.com>
Sun, 14 Feb 2016 23:22:53 +0000 (00:22 +0100)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 15 Feb 2016 14:01:45 +0000 (14:01 +0000)
This adds the defenses needed to make sure this context does not get
abused.

Change-Id: I8ab60018d567715ab96c0e0ff4cfcf8f0c412793
Signed-off-by: Robert Varga <rovarga@cisco.com>
dom/mdsal-dom-inmemory-datastore/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/ForeignShardModificationContext.java

index e0626bdc9607241c6073b7b9b423f0c3f19e19b4..bb32047f8f1a04b04ee10f57a64a0d0f63200f58 100644 (file)
@@ -9,15 +9,20 @@
 package org.opendaylight.mdsal.dom.store.inmemory;
 
 import com.google.common.base.Preconditions;
+import javax.annotation.concurrent.NotThreadSafe;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-class ForeignShardModificationContext {
-
+@NotThreadSafe
+final class ForeignShardModificationContext {
+    private static final Logger LOG = LoggerFactory.getLogger(ForeignShardModificationContext.class);
     private final DOMDataTreeIdentifier identifier;
     private final DOMDataTreeShardProducer producer;
     private DOMDataTreeShardWriteTransaction tx;
     private DOMDataTreeWriteCursor cursor;
+    private volatile boolean notReady = true;
 
     ForeignShardModificationContext(final DOMDataTreeIdentifier identifier, final DOMDataTreeShardProducer producer) {
         this.identifier = Preconditions.checkNotNull(identifier);
@@ -25,10 +30,12 @@ class ForeignShardModificationContext {
     }
 
     DOMDataTreeWriteCursor getCursor() {
-        if (tx == null) {
-            tx = producer.createTransaction();
-        }
+        Preconditions.checkState(notReady, "Context %s has been readied", this);
+
         if (cursor == null) {
+            if (tx == null) {
+                tx = producer.createTransaction();
+            }
             cursor = tx.createCursor(getIdentifier());
         }
         return cursor;
@@ -39,13 +46,21 @@ class ForeignShardModificationContext {
     }
 
     void ready() {
-        // FIXME: mark the fact this is ready, prevent instantiation of cursor
+        if (!notReady) {
+            // Idempotent, but emit a debug
+            LOG.debug("Duplicate ready() of context {}", this);
+            return;
+        }
+
+        notReady = true;
         if (cursor != null) {
             cursor.close();
-
-            if (tx != null) {
-                tx.ready();
-            }
+            cursor = null;
+        }
+        if (tx != null) {
+            tx.ready();
+            // TODO: it would be nice if we could clear this reference
+            // tx = null;
         }
     }