2 * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.config.manager.impl;
11 import java.util.Deque;
12 import java.util.LinkedList;
13 import java.util.concurrent.TimeUnit;
14 import javax.annotation.Nullable;
15 import javax.annotation.concurrent.GuardedBy;
16 import org.opendaylight.controller.config.api.ModuleIdentifier;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
20 public class DeadlockMonitor implements AutoCloseable {
21 private static final Logger LOG = LoggerFactory.getLogger(DeadlockMonitor.class);
23 private static final long WARN_AFTER_MILLIS = 5000;
25 private final TransactionIdentifier transactionIdentifier;
26 private final DeadlockMonitorRunnable thread;
28 private final Deque<ModuleIdentifierWithNanos> moduleIdentifierWithNanosStack = new LinkedList<>();
30 private ModuleIdentifierWithNanos top = ModuleIdentifierWithNanos.EMPTY;
32 public DeadlockMonitor(TransactionIdentifier transactionIdentifier) {
33 this.transactionIdentifier = transactionIdentifier;
34 thread = new DeadlockMonitorRunnable();
38 public synchronized void setCurrentlyInstantiatedModule(ModuleIdentifier currentlyInstantiatedModule) {
40 boolean popping = currentlyInstantiatedModule == null;
42 moduleIdentifierWithNanosStack.pop();
43 if (moduleIdentifierWithNanosStack.isEmpty()) {
44 top = ModuleIdentifierWithNanos.EMPTY;
46 top = moduleIdentifierWithNanosStack.peekLast();
49 ModuleIdentifierWithNanos current = new ModuleIdentifierWithNanos(currentlyInstantiatedModule);
50 moduleIdentifierWithNanosStack.push(current);
53 LOG.trace("setCurrentlyInstantiatedModule {}, top {}", currentlyInstantiatedModule, top);
56 public boolean isAlive() {
57 return thread.isAlive();
66 public String toString() {
67 return "DeadlockMonitor{" + transactionIdentifier + '}';
70 private class DeadlockMonitorRunnable extends Thread {
72 private DeadlockMonitorRunnable() {
73 super(DeadlockMonitor.this.toString());
78 ModuleIdentifierWithNanos old = new ModuleIdentifierWithNanos(); // null moduleId
79 while (this.isInterrupted() == false) {
80 ModuleIdentifierWithNanos copy;
82 copy = new ModuleIdentifierWithNanos(DeadlockMonitor.this.top);
85 if (old.moduleIdentifier == null || old.equals(copy) == false) {
89 // is the getInstance() running longer than WARN_AFTER_MILLIS ?
90 long runningTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - copy.nanoTime);
91 if (runningTime > WARN_AFTER_MILLIS) {
92 LOG.warn("{} did not finish after {} ms", copy.moduleIdentifier, runningTime);
96 sleep(WARN_AFTER_MILLIS);
97 } catch (InterruptedException e) {
101 LOG.trace("Exiting {}", this);
105 public String toString() {
106 return "DeadLockMonitorRunnable{" + transactionIdentifier + "}";
113 private static class ModuleIdentifierWithNanos {
114 private static ModuleIdentifierWithNanos EMPTY = new ModuleIdentifierWithNanos();
116 private final ModuleIdentifier moduleIdentifier;
118 private final long nanoTime;
120 private ModuleIdentifierWithNanos() {
121 this((ModuleIdentifier)null);
124 private ModuleIdentifierWithNanos(ModuleIdentifier moduleIdentifier) {
125 this.moduleIdentifier = moduleIdentifier;
126 nanoTime = System.nanoTime();
129 private ModuleIdentifierWithNanos(ModuleIdentifierWithNanos copy) {
130 moduleIdentifier = copy.moduleIdentifier;
131 nanoTime = copy.nanoTime;
135 public boolean equals(Object o) {
139 if (o == null || getClass() != o.getClass()) {
143 ModuleIdentifierWithNanos that = (ModuleIdentifierWithNanos) o;
145 if (nanoTime != that.nanoTime) {
148 if (moduleIdentifier != null ? !moduleIdentifier.equals(that.moduleIdentifier) : that.moduleIdentifier != null) {
156 public int hashCode() {
157 int result = moduleIdentifier != null ? moduleIdentifier.hashCode() : 0;
158 result = 31 * result + (int) (nanoTime ^ (nanoTime >>> 32));
163 public String toString() {
164 return "ModuleIdentifierWithNanos{" +