X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fconfig%2Fconfig-manager%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fconfig%2Fmanager%2Fimpl%2FDeadlockMonitor.java;h=cad98b30f4edd9a3f2689fd43bfa0a6127316103;hb=81674d6fd50b419b868d0851062e23f34b34557d;hp=ba7ab7fcba924743c4ea579797f1dffbd117c7cb;hpb=c0c97bdca0c42607e8034bc91f51edf96d9e72a9;p=controller.git diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/DeadlockMonitor.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/DeadlockMonitor.java index ba7ab7fcba..cad98b30f4 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/DeadlockMonitor.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/DeadlockMonitor.java @@ -1,31 +1,56 @@ +/* + * Copyright (c) 2014, 2017 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + package org.opendaylight.controller.config.manager.impl; +import java.util.Deque; +import java.util.LinkedList; +import java.util.concurrent.TimeUnit; +import javax.annotation.Nullable; +import javax.annotation.concurrent.GuardedBy; import org.opendaylight.controller.config.api.ModuleIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.Nullable; -import javax.annotation.concurrent.GuardedBy; -import java.util.concurrent.TimeUnit; - public class DeadlockMonitor implements AutoCloseable { - private static final Logger logger = LoggerFactory.getLogger(DeadlockMonitorRunnable.class); + private static final Logger LOG = LoggerFactory.getLogger(DeadlockMonitor.class); private static final long WARN_AFTER_MILLIS = 5000; private final TransactionIdentifier transactionIdentifier; private final DeadlockMonitorRunnable thread; @GuardedBy("this") - private ModuleIdentifierWithNanos moduleIdentifierWithNanos = new ModuleIdentifierWithNanos(); + private final Deque moduleIdentifierWithNanosStack = new LinkedList<>(); + @GuardedBy("this") + private ModuleIdentifierWithNanos top = ModuleIdentifierWithNanos.empty; - public DeadlockMonitor(TransactionIdentifier transactionIdentifier) { + public DeadlockMonitor(final TransactionIdentifier transactionIdentifier) { this.transactionIdentifier = transactionIdentifier; thread = new DeadlockMonitorRunnable(); thread.start(); } - public synchronized void setCurrentlyInstantiatedModule(ModuleIdentifier currentlyInstantiatedModule) { - this.moduleIdentifierWithNanos = new ModuleIdentifierWithNanos(currentlyInstantiatedModule); + public synchronized void setCurrentlyInstantiatedModule(final ModuleIdentifier currentlyInstantiatedModule) { + + boolean popping = currentlyInstantiatedModule == null; + if (popping) { + moduleIdentifierWithNanosStack.pop(); + if (moduleIdentifierWithNanosStack.isEmpty()) { + top = ModuleIdentifierWithNanos.empty; + } else { + top = moduleIdentifierWithNanosStack.peekLast(); + } + } else { + ModuleIdentifierWithNanos current = new ModuleIdentifierWithNanos(currentlyInstantiatedModule); + moduleIdentifierWithNanosStack.push(current); + top = current; + } + LOG.trace("setCurrentlyInstantiatedModule {}, top {}", currentlyInstantiatedModule, top); } public boolean isAlive() { @@ -50,26 +75,31 @@ public class DeadlockMonitor implements AutoCloseable { @Override public void run() { - ModuleIdentifierWithNanos old = new ModuleIdentifierWithNanos(); // null moduleId - while (this.isInterrupted() == false) { - ModuleIdentifierWithNanos copy = new ModuleIdentifierWithNanos(DeadlockMonitor.this.moduleIdentifierWithNanos); - if (old.moduleIdentifier == null) { + // null moduleId + ModuleIdentifierWithNanos old = new ModuleIdentifierWithNanos(); + while (!this.isInterrupted()) { + ModuleIdentifierWithNanos copy; + synchronized (this) { + copy = new ModuleIdentifierWithNanos(DeadlockMonitor.this.top); + } + + if (old.moduleIdentifier == null || !old.equals(copy)) { // started old = copy; - } else if (old.moduleIdentifier != null && old.equals(copy)) { + } else { // is the getInstance() running longer than WARN_AFTER_MILLIS ? long runningTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - copy.nanoTime); if (runningTime > WARN_AFTER_MILLIS) { - logger.warn("{} did not finish after {} ms", copy.moduleIdentifier, runningTime); + LOG.warn("{} did not finish after {} ms", copy.moduleIdentifier, runningTime); } } try { - sleep(1000); - } catch (InterruptedException e) { + sleep(WARN_AFTER_MILLIS); + } catch (final InterruptedException e) { interrupt(); } } - logger.trace("Exiting {}", this); + LOG.trace("Exiting {}", this); } @Override @@ -78,36 +108,45 @@ public class DeadlockMonitor implements AutoCloseable { } } - private class ModuleIdentifierWithNanos { + private static class ModuleIdentifierWithNanos { + private static ModuleIdentifierWithNanos empty = new ModuleIdentifierWithNanos(); @Nullable private final ModuleIdentifier moduleIdentifier; + private final long nanoTime; private ModuleIdentifierWithNanos() { - moduleIdentifier = null; - nanoTime = System.nanoTime(); + this((ModuleIdentifier) null); } - private ModuleIdentifierWithNanos(ModuleIdentifier moduleIdentifier) { + private ModuleIdentifierWithNanos(final ModuleIdentifier moduleIdentifier) { this.moduleIdentifier = moduleIdentifier; nanoTime = System.nanoTime(); } - private ModuleIdentifierWithNanos(ModuleIdentifierWithNanos copy) { + private ModuleIdentifierWithNanos(final ModuleIdentifierWithNanos copy) { moduleIdentifier = copy.moduleIdentifier; nanoTime = copy.nanoTime; } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + public boolean equals(final Object object) { + if (this == object) { + return true; + } + if (object == null || getClass() != object.getClass()) { + return false; + } - ModuleIdentifierWithNanos that = (ModuleIdentifierWithNanos) o; + ModuleIdentifierWithNanos that = (ModuleIdentifierWithNanos) object; - if (nanoTime != that.nanoTime) return false; - if (moduleIdentifier != null ? !moduleIdentifier.equals(that.moduleIdentifier) : that.moduleIdentifier != null) + if (nanoTime != that.nanoTime) { return false; + } + if (moduleIdentifier != null ? !moduleIdentifier.equals(that.moduleIdentifier) + : that.moduleIdentifier != null) { + return false; + } return true; } @@ -115,8 +154,13 @@ public class DeadlockMonitor implements AutoCloseable { @Override public int hashCode() { int result = moduleIdentifier != null ? moduleIdentifier.hashCode() : 0; - result = 31 * result + (int) (nanoTime ^ (nanoTime >>> 32)); + result = 31 * result + (int) (nanoTime ^ nanoTime >>> 32); return result; } + + @Override + public String toString() { + return "ModuleIdentifierWithNanos{" + moduleIdentifier + '}'; + } } }