From c3607fd866e5cfde0d4806820981fe95ad29392c Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Thu, 15 Dec 2016 14:24:47 +0100 Subject: [PATCH] BUG-5280: synchronize access to local histories There is a subtle race between the allocation of histories and the reconnect process, which could allow a local history to be created when its connection is being reestablished but after the cohorts for the connection have already been captured. Change-Id: I230b5c00844d8e82775efc8f70368c2f63eabb1e Signed-off-by: Robert Varga --- .../dds/AbstractDataStoreClientBehavior.java | 55 ++++++++++++------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/AbstractDataStoreClientBehavior.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/AbstractDataStoreClientBehavior.java index 202fe5b8fa..9af88a8a5a 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/AbstractDataStoreClientBehavior.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/AbstractDataStoreClientBehavior.java @@ -16,6 +16,7 @@ import java.util.Collection; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.StampedLock; import org.opendaylight.controller.cluster.access.client.BackendInfoResolver; import org.opendaylight.controller.cluster.access.client.ClientActorBehavior; import org.opendaylight.controller.cluster.access.client.ClientActorContext; @@ -62,6 +63,7 @@ abstract class AbstractDataStoreClientBehavior extends ClientActorBehavior histories = new ConcurrentHashMap<>(); private final AtomicLong nextHistoryId = new AtomicLong(1); + private final StampedLock lock = new StampedLock(); private final SingleClientHistory singleHistory; private volatile Throwable aborted; @@ -89,14 +91,19 @@ abstract class AbstractDataStoreClientBehavior extends ClientActorBehavior currentBehavior) { @@ -121,6 +128,8 @@ abstract class AbstractDataStoreClientBehavior extends ClientActorBehavior newConn) { + final long stamp = lock.writeLock(); + // Step 1: Freeze all AbstractProxyHistory instances pointing to that shard. This indirectly means that no // further TransactionProxies can be created and we can safely traverse maps without risking // missing an entry @@ -143,9 +152,13 @@ abstract class AbstractDataStoreClientBehavior extends ClientActorBehavior