X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-binding-broker%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fmd%2Fsal%2Fbinding%2Fimpl%2FFutureSchema.java;h=fb70811840e4cbaa935e1523db64e54ea71036ff;hp=2898ba7e37ca9729e0f0c113f8e6d34da3f9a188;hb=7257dc4ecacf3e4d08273c31accd945fb8f3e769;hpb=2cf157241dc0ce5045c26e2ad07d053a60b37822 diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/FutureSchema.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/FutureSchema.java index 2898ba7e37..fb70811840 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/FutureSchema.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/FutureSchema.java @@ -13,29 +13,51 @@ import com.google.common.base.Throwables; import com.google.common.util.concurrent.SettableFuture; import java.net.URI; import java.util.Collection; +import java.util.Collections; import java.util.Date; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; +import java.util.LinkedHashSet; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import javax.annotation.concurrent.GuardedBy; import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext; import org.opendaylight.yangtools.yang.binding.Augmentation; class FutureSchema implements AutoCloseable { - private final List postponedOperations = new CopyOnWriteArrayList<>(); + @GuardedBy(value="postponedOperations") + private final Set postponedOperations = new LinkedHashSet<>(); private final long duration; private final TimeUnit unit; + private final boolean waitEnabled; + private volatile BindingRuntimeContext runtimeContext; - protected FutureSchema(final long time, final TimeUnit unit) { + protected FutureSchema(final long time, final TimeUnit unit, final boolean waitEnabled) { this.duration = time; this.unit = unit; + this.waitEnabled = waitEnabled; + } + + BindingRuntimeContext runtimeContext() { + BindingRuntimeContext localRuntimeContext = runtimeContext; + if(localRuntimeContext != null) { + return localRuntimeContext; + } + + if(waitForSchema(Collections.emptyList())) { + return runtimeContext; + } + + throw new IllegalStateException("No SchemaContext is available"); } void onRuntimeContextUpdated(final BindingRuntimeContext context) { - for (final FutureSchemaPredicate op : postponedOperations) { - op.unlockIfPossible(context); + synchronized(postponedOperations) { + runtimeContext = context; + for (final FutureSchemaPredicate op : postponedOperations) { + op.unlockIfPossible(context); + } } } @@ -49,8 +71,10 @@ class FutureSchema implements AutoCloseable { @Override public void close() { - for (final FutureSchemaPredicate op : postponedOperations) { - op.cancel(); + synchronized(postponedOperations) { + for (final FutureSchemaPredicate op : postponedOperations) { + op.cancel(); + } } } @@ -65,19 +89,16 @@ class FutureSchema implements AutoCloseable { } boolean waitForSchema(final URI namespace, final Date revision) { - final FutureSchemaPredicate postponedOp = new FutureSchemaPredicate() { - + return addPostponedOpAndWait(new FutureSchemaPredicate() { @Override public boolean apply(final BindingRuntimeContext input) { return input.getSchemaContext().findModuleByNamespaceAndRevision(namespace, revision) != null; } - }; - return postponedOp.waitForSchema(); + }); } boolean waitForSchema(final Collection> bindingClasses) { - final FutureSchemaPredicate postponedOp = new FutureSchemaPredicate() { - + return addPostponedOpAndWait(new FutureSchemaPredicate() { @Override public boolean apply(final BindingRuntimeContext context) { for (final Class clz : bindingClasses) { @@ -87,7 +108,24 @@ class FutureSchema implements AutoCloseable { } return true; } - }; + }); + } + + private boolean addPostponedOpAndWait(FutureSchemaPredicate postponedOp) { + if(!waitEnabled) { + return false; + } + + BindingRuntimeContext localRuntimeContext = runtimeContext; + synchronized(postponedOperations) { + postponedOperations.add(postponedOp); + + // If the runtimeContext changed, this op may now be satisfied so check it. + if(localRuntimeContext != runtimeContext) { + postponedOp.unlockIfPossible(runtimeContext); + } + } + return postponedOp.waitForSchema(); } @@ -102,7 +140,9 @@ class FutureSchema implements AutoCloseable { } catch (final TimeoutException e) { return false; } finally { - postponedOperations.remove(this); + synchronized(postponedOperations) { + postponedOperations.remove(this); + } } }