X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-dom-broker%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fmd%2Fsal%2Fdom%2Fstore%2Fimpl%2Ftree%2Fdata%2FInMemoryDataTreeModification.java;h=f7e95b84bd4df38c214c32f10c1b01df61fb4798;hb=da4cff5c3a5bc732fb046b563b886a7aaab67c30;hp=fcb3ae0a10cf9028193dcdb60cea8a3a432664b3;hpb=21ac8568d134427df8b1539a0648377cf74d70d1;p=controller.git diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java index fcb3ae0a10..f7e95b84bd 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java @@ -7,13 +7,11 @@ */ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; -import static com.google.common.base.Preconditions.checkState; - import java.util.Map.Entry; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; + +import javax.annotation.concurrent.GuardedBy; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils; import org.opendaylight.controller.md.sal.dom.store.impl.tree.TreeNodeUtils; import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; @@ -29,19 +27,13 @@ import com.google.common.base.Preconditions; final class InMemoryDataTreeModification implements DataTreeModification { private static final Logger LOG = LoggerFactory.getLogger(InMemoryDataTreeModification.class); - - /* - * FIXME: the thread safety of concurrent write/delete/read/seal operations - * needs to be evaluated. - */ - private static final AtomicIntegerFieldUpdater SEALED_UPDATER = - AtomicIntegerFieldUpdater.newUpdater(InMemoryDataTreeModification.class, "sealed"); - private volatile int sealed = 0; - private final ModificationApplyOperation strategyTree; private final InMemoryDataTreeSnapshot snapshot; private final ModifiedNode rootNode; + @GuardedBy("this") + private boolean sealed = false; + InMemoryDataTreeModification(final InMemoryDataTreeSnapshot snapshot, final ModificationApplyOperation resolver) { this.snapshot = Preconditions.checkNotNull(snapshot); this.strategyTree = Preconditions.checkNotNull(resolver); @@ -57,13 +49,13 @@ final class InMemoryDataTreeModification implements DataTreeModification { } @Override - public void write(final InstanceIdentifier path, final NormalizedNode value) { + public synchronized void write(final InstanceIdentifier path, final NormalizedNode value) { checkSealed(); resolveModificationFor(path).write(value); } @Override - public void merge(final InstanceIdentifier path, final NormalizedNode data) { + public synchronized void merge(final InstanceIdentifier path, final NormalizedNode data) { checkSealed(); mergeImpl(resolveModificationFor(path),data); } @@ -82,13 +74,13 @@ final class InMemoryDataTreeModification implements DataTreeModification { } @Override - public void delete(final InstanceIdentifier path) { + public synchronized void delete(final InstanceIdentifier path) { checkSealed(); resolveModificationFor(path).delete(); } @Override - public Optional> readNode(final InstanceIdentifier path) { + public synchronized Optional> readNode(final InstanceIdentifier path) { /* * Walk the tree from the top, looking for the first node between root and * the requested path which has been modified. If no such node exists, @@ -116,7 +108,7 @@ final class InMemoryDataTreeModification implements DataTreeModification { try { return resolveModificationStrategy(path).apply(modification, modification.getOriginal(), - StoreUtils.increase(snapshot.getRootNode().getSubtreeVersion())); + snapshot.getRootNode().getSubtreeVersion().next()); } catch (Exception e) { LOG.error("Could not create snapshot for {}:{}", path,modification,e); throw e; @@ -139,14 +131,15 @@ final class InMemoryDataTreeModification implements DataTreeModification { } @Override - public void seal() { - final boolean success = SEALED_UPDATER.compareAndSet(this, 0, 1); - Preconditions.checkState(success, "Attempted to seal an already-sealed Data Tree."); + public synchronized void ready() { + Preconditions.checkState(!sealed, "Attempted to seal an already-sealed Data Tree."); + sealed = true; rootNode.seal(); } + @GuardedBy("this") private void checkSealed() { - checkState(sealed == 0, "Data Tree is sealed. No further modifications allowed."); + Preconditions.checkState(!sealed, "Data Tree is sealed. No further modifications allowed."); } @Override @@ -155,7 +148,9 @@ final class InMemoryDataTreeModification implements DataTreeModification { } @Override - public DataTreeModification newModification() { + public synchronized DataTreeModification newModification() { + Preconditions.checkState(sealed, "Attempted to chain on an unsealed modification"); + // FIXME: transaction chaining throw new UnsupportedOperationException("Implement this as part of transaction chaining"); }