1 4 package com.tc.objectserver.lockmanager.impl; 5 6 import com.tc.objectserver.lockmanager.api.DeadlockResults; 7 8 import java.util.ArrayList ; 9 import java.util.Collection ; 10 import java.util.HashSet ; 11 import java.util.Iterator ; 12 import java.util.List ; 13 import java.util.Set ; 14 15 class DeadlockDetector { 16 private static final ServerThreadContext[] EMPTY_TXN_ARRAY = new ServerThreadContext[] {}; 17 18 private final DeadlockResults listener; 19 private final Set inDeadlock = new HashSet (); 20 21 DeadlockDetector(DeadlockResults listener) { 22 this.listener = listener; 23 } 24 25 void detect(Iterator openTransactions) { 26 while (openTransactions.hasNext()) { 27 ServerThreadContext txn = (ServerThreadContext) openTransactions.next(); 28 txn.setCycle(null); 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 holders = waitingOn.getHoldersCollection(); 41 42 for (final Iterator 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 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 getTransactionsInCycle(ServerThreadContext me, ServerThreadContext them) { 89 List txns = new ArrayList (); 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 |