Another speedup -- as it turns out we do not have to take the full lock
to close down the transaction factory. A volatile write is enough to do
that -- which means a volatile read is enough to check for it having
been closed.
Change-Id: I3488ccccc4d91d34665b3ff6e70e047407be48bb
Signed-off-by: Robert Varga <rovarga@cisco.com>
import java.util.EnumMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.EnumMap;
import java.util.Map;
import java.util.Map.Entry;
-import javax.annotation.concurrent.GuardedBy;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
* @param <T>
* Type of {@link DOMStoreTransactionFactory} factory.
*/
* @param <T>
* Type of {@link DOMStoreTransactionFactory} factory.
*/
-public abstract class AbstractDOMForwardedTransactionFactory<T extends DOMStoreTransactionFactory> implements DOMDataCommitImplementation, AutoCloseable {
-
+abstract class AbstractDOMForwardedTransactionFactory<T extends DOMStoreTransactionFactory> implements DOMDataCommitImplementation, AutoCloseable {
+ @SuppressWarnings("rawtypes")
+ private static final AtomicIntegerFieldUpdater<AbstractDOMForwardedTransactionFactory> UPDATER =
+ AtomicIntegerFieldUpdater.newUpdater(AbstractDOMForwardedTransactionFactory.class, "closed");
private final Map<LogicalDatastoreType, T> storeTxFactories;
private final Map<LogicalDatastoreType, T> storeTxFactories;
-
- private boolean closed;
+ private volatile int closed = 0;
protected AbstractDOMForwardedTransactionFactory(final Map<LogicalDatastoreType, ? extends T> txFactories) {
this.storeTxFactories = ImmutableMap.copyOf(txFactories);
protected AbstractDOMForwardedTransactionFactory(final Map<LogicalDatastoreType, ? extends T> txFactories) {
this.storeTxFactories = ImmutableMap.copyOf(txFactories);
*
* @return New composite read-only transaction.
*/
*
* @return New composite read-only transaction.
*/
- public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
+ public final DOMDataReadOnlyTransaction newReadOnlyTransaction() {
checkNotClosed();
final Map<LogicalDatastoreType, DOMStoreReadTransaction> txns = new EnumMap<>(LogicalDatastoreType.class);
checkNotClosed();
final Map<LogicalDatastoreType, DOMStoreReadTransaction> txns = new EnumMap<>(LogicalDatastoreType.class);
return new DOMForwardedReadOnlyTransaction(newTransactionIdentifier(), txns);
}
return new DOMForwardedReadOnlyTransaction(newTransactionIdentifier(), txns);
}
/**
* Creates a new composite write-only transaction
*
/**
* Creates a new composite write-only transaction
*
* @return New composite write-only transaction associated with this
* factory.
*/
* @return New composite write-only transaction associated with this
* factory.
*/
- public DOMDataWriteTransaction newWriteOnlyTransaction() {
+ public final DOMDataWriteTransaction newWriteOnlyTransaction() {
checkNotClosed();
final Map<LogicalDatastoreType, DOMStoreWriteTransaction> txns = new EnumMap<>(LogicalDatastoreType.class);
checkNotClosed();
final Map<LogicalDatastoreType, DOMStoreWriteTransaction> txns = new EnumMap<>(LogicalDatastoreType.class);
*
* @return New composite read-write transaction associated with this
* factory.
*
* @return New composite read-write transaction associated with this
* factory.
- public DOMDataReadWriteTransaction newReadWriteTransaction() {
+ public final DOMDataReadWriteTransaction newReadWriteTransaction() {
checkNotClosed();
final Map<LogicalDatastoreType, DOMStoreReadWriteTransaction> txns = new EnumMap<>(LogicalDatastoreType.class);
checkNotClosed();
final Map<LogicalDatastoreType, DOMStoreReadWriteTransaction> txns = new EnumMap<>(LogicalDatastoreType.class);
* Checks if instance is not closed.
*
* @throws IllegalStateException If instance of this class was closed.
*
*/
* Checks if instance is not closed.
*
* @throws IllegalStateException If instance of this class was closed.
*
*/
- @GuardedBy("this")
- protected synchronized void checkNotClosed() {
- Preconditions.checkState(!closed,"Transaction factory was closed. No further operations allowed.");
+ protected final void checkNotClosed() {
+ Preconditions.checkState(closed == 0, "Transaction factory was closed. No further operations allowed.");
- @GuardedBy("this")
- public synchronized void close() {
- closed = true;
+ public void close() {
+ final int wasClosed = UPDATER.getAndSet(this, 1);
+ Preconditions.checkState(wasClosed == 0, "Transaction factory was already closed");
return getSubtransaction(store).read(path);
}
return getSubtransaction(store).read(path);
}
- @Override public CheckedFuture<Boolean, ReadFailedException> exists(
+ @Override
+ public CheckedFuture<Boolean, ReadFailedException> exists(
final LogicalDatastoreType store,
final YangInstanceIdentifier path) {
return getSubtransaction(store).exists(path);
final LogicalDatastoreType store,
final YangInstanceIdentifier path) {
return getSubtransaction(store).exists(path);