Make sure TransactionInvokerImpl chain is properly protected 80/86280/15
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 6 Dec 2019 21:08:28 +0000 (22:08 +0100)
committerStephen Kitt <skitt@redhat.com>
Tue, 7 Jan 2020 16:04:52 +0000 (16:04 +0000)
TransactionChains require single-threaded access, most notably
their close() contract requires that there be no outstanding
transactions.

There is a slight possibility of us violating this contract by
invoking close() while there is some command processing going
on.

Make sure we are properly synchronized when invoking the close()
call.

Change-Id: Idacc7096af448dc3a935ca3aa7ea2452bbd0135e
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/TransactionInvokerImpl.java

index 7dcdbd74fd26be24b299f1ded6f5e6f28649f7c7..6773d43f8ca7766c9c37642094f8529ec741a5f6 100644 (file)
@@ -50,7 +50,7 @@ public class TransactionInvokerImpl implements TransactionInvoker,TransactionCha
 
     @GuardedBy("this")
     private final Queue<Entry<ReadWriteTransaction, TransactionCommand>> pendingTransactions = new ArrayDeque<>();
-
+    @GuardedBy("this")
     private BindingTransactionChain chain;
 
     public TransactionInvokerImpl(final DataBroker db) {
@@ -223,8 +223,12 @@ public class TransactionInvokerImpl implements TransactionInvoker,TransactionCha
 
     @Override
     public void close() throws InterruptedException {
-        this.chain.close();
         this.executor.shutdown();
+
+        synchronized (this) {
+            this.chain.close();
+        }
+
         if (!this.executor.awaitTermination(1, TimeUnit.SECONDS)) {
             runTask.set(false);
             this.executor.shutdownNow();