KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > objectserver > lockmanager > impl > DeadlockDetector


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.objectserver.lockmanager.impl;
5
6 import com.tc.objectserver.lockmanager.api.DeadlockResults;
7
8 import java.util.ArrayList JavaDoc;
9 import java.util.Collection JavaDoc;
10 import java.util.HashSet JavaDoc;
11 import java.util.Iterator JavaDoc;
12 import java.util.List JavaDoc;
13 import java.util.Set JavaDoc;
14
15 class DeadlockDetector {
16   private static final ServerThreadContext[] EMPTY_TXN_ARRAY = new ServerThreadContext[] {};
17
18   private final DeadlockResults listener;
19   private final Set JavaDoc inDeadlock = new HashSet JavaDoc();
20
21   DeadlockDetector(DeadlockResults listener) {
22     this.listener = listener;
23   }
24
25   void detect(Iterator JavaDoc openTransactions) {
26     while (openTransactions.hasNext()) {
27       ServerThreadContext txn = (ServerThreadContext) openTransactions.next();
28       txn.setCycle(null); // null this out just in case it was corrupted by some exception in a previous scan
29

30       if (!inDeadlock.contains(txn)) {
31         visit(txn);
32       }
33     }
34   }
35
36   private void visit(final ServerThreadContext me) {
37     if (!me.isWaiting()) return;
38
39     final Lock waitingOn = me.getWaitingOn();
40     final Collection JavaDoc holders = waitingOn.getHoldersCollection();
41
42     for (final Iterator JavaDoc iter = holders.iterator(); iter.hasNext();) {
43       Holder holder = (Holder) iter.next();
44       ServerThreadContext them = holder.getThreadContext();
45
46       if (!them.equals(me)) {
47         if (them.isWaiting()) {
48           me.setCycle(them);
49           if (them.getCycle() != null) {
50             handleDeadlock(me, them);
51           } else {
52             visit(them);
53           }
54           me.setCycle(null);
55         }
56       }
57     }
58   }
59
60   private void handleDeadlock(ServerThreadContext me, ServerThreadContext them) {
61     List JavaDoc txnList = getTransactionsInCycle(me, them);
62     inDeadlock.addAll(txnList);
63
64     DeadlockChainImpl head = null;
65     DeadlockChainImpl link = null;
66
67     ServerThreadContext[] txnArray = (ServerThreadContext[]) txnList.toArray(EMPTY_TXN_ARRAY);
68     for (int i = 0, n = txnArray.length; i < n; i++) {
69       ServerThreadContext txn = txnArray[i];
70       DeadlockChainImpl tmp = new DeadlockChainImpl(txn.getId(), txn.getWaitingOn().getLockID());
71
72       if (head == null) {
73         head = tmp;
74       }
75
76       if (link != null) {
77         link.setNextLink(tmp);
78       }
79
80       link = tmp;
81     }
82
83     link.setNextLink(head);
84
85     listener.foundDeadlock(head);
86   }
87
88   private static List JavaDoc getTransactionsInCycle(ServerThreadContext me, ServerThreadContext them) {
89     List JavaDoc txns = new ArrayList JavaDoc();
90     txns.add(me);
91
92     do {
93       txns.add(them);
94       them = them.getCycle();
95     } while (!them.equals(me));
96
97     return txns;
98   }
99 }
100
Popular Tags