KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ozoneDB > core > dr > EdgeChasing


1 // You can redistribute this software and/or modify it under the terms of
2
// the Ozone Core License version 1 published by ozone-db.org.
3
//
4
// The original code and portions created by SMB are
5
// Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
6
//
7
// $Id: EdgeChasing.java,v 1.5 2002/12/29 11:15:57 per_nyfelt Exp $
8

9 package org.ozoneDB.core.dr;
10
11 import java.util.HashSet JavaDoc;
12
13 import org.ozoneDB.DxLib.*;
14 import org.ozoneDB.core.*;
15 import org.ozoneDB.util.*;
16
17 /**
18  * @author <a HREF="http://www.softwarebuero.de/">SMB</a>
19  * @version $Revision: 1.5 $Date: 2002/12/29 11:15:57 $
20  */

21 public final class EdgeChasing extends DeadlockRecognition {
22
23     protected Env env;
24
25
26     public EdgeChasing( Env _env ) {
27         this.env = _env;
28     }
29
30
31     public Locker detectDeadlock( Locker locker ) {
32 // env.logWriter.newEntry( this, "*** detectDeadlock(): " + locker, LogWriter.DEBUG );
33
// return sendLockMessage( locker, locker, true ) ? locker : null;
34
return sendLockMessage( locker, locker, true );
35     }
36
37
38     /**
39      * Recursive deadlock recognition.
40      * @return True, if this transaction is blocked by root (?)
41      */

42     public Locker sendLockMessage( Locker root, Locker locker, boolean firstLevel ) {
43         HashSet JavaDoc visitingLockers = new HashSet JavaDoc(); // The lockers we are currently already visiting
44

45         return sendLockMessage(root,locker,firstLevel,visitingLockers);
46     }
47
48     /**
49      * Recursive deadlock recognition.
50      * @return True, if this transaction is blocked by root (?)
51      */

52     public Locker sendLockMessage(Locker root,Locker locker,boolean firstLevel,HashSet JavaDoc visitingLockers) {
53         if (!locker.isDeadlocked()) {
54             if (visitingLockers.add(locker)) {
55                 try {
56                     env.logWriter.newEntry( this, "*** sendLockMessage(): " + locker+", visitingLockers="+visitingLockers+".", LogWriter.DEBUG );
57                     Lockable blocker = locker.blockedBy();
58
59                     if (blocker == null) {
60                         return null;
61                     }
62
63                     try {
64                         if (!firstLevel) {
65                             if (root == locker) {
66                                 return null;
67                             }
68
69                             if (blocker == null) {
70                                 return null;
71                             }
72                         }
73
74                         //bin selbst beim warten auf blocker blockiert; wenn ich
75
//lese-lock setzen moechte, muss ich die ta mit schreib-lock
76
//auf blocker kontrollieren; wenn schreib-lock alle ta mit
77
//lese-lock auf blocker - diese werden genau von allLockers()
78
//geliefert
79

80                         //alle ta, die mich behindern; entweder ein schreibende oder
81
//viele lesende transaktionen
82
DxCollection lockers = blocker.allLockers();
83                         Locker deadLockingLocker = null;
84
85                         if (lockers != null) {
86                             DxIterator it = lockers.iterator();
87
88                             while (it.next() != null) {
89                                 Locker nextLocker = (Locker)it.object();
90                                 if (nextLocker != locker) {
91                                     if (visitingLockers.contains(nextLocker)) {
92                                         deadLockingLocker = nextLocker;
93                                         /*
94                                             We know we already are deadlocking. But let's traverse deeper if possible.
95                                             In this case, we could find a second deadlock ring which the first depends
96                                             on.
97
98                                             What if we find a deadLockingLocker, it is the only one, but a locker which this
99                                             locker depends on still has some locker free? If we still get deadlock-livelocks
100                                             (deadlocks are resolved but they happen again and again in the same way), we
101                                             have to consider this.
102
103                                             Oh, these livelocks just happened..
104                                         */

105                                         nextLocker.setDeadlocked(true);
106                                     } else {
107     // deadLockingLocker = null;
108
}
109                                     //we are done if we have detected the first circle;
110
//go on with next candidate otherwise
111

112                                     Locker deadlocker = sendLockMessage(root,nextLocker,false,visitingLockers);
113
114                                     // We continue our traversal until we reached every potential deadlocker (we have to do this due to deadlock-loops)
115
if (deadlocker!=null) {
116                                         if (false) {
117                                             return deadlocker;
118                                         } else {
119                                             deadLockingLocker = deadlocker;
120                                         }
121                                     }
122                                 }
123                             }
124                         }
125
126                         return deadLockingLocker;
127                     } finally {
128                         blocker.unpin();
129                     }
130                 } finally {
131                     visitingLockers.remove(locker);
132                 }
133             } else {
134                 if (!locker.isDeadlocked()) {
135                     locker.setDeadlocked(true);
136                     env.logWriter.newEntry(this,"sendLockMessage(): We are about to visit "+locker+" twice (visitingLockers="+visitingLockers+"). This must not be because we would loop.",LogWriter.ERROR);
137                 } else {
138                     env.logWriter.newEntry(this,"sendLockMessage(): We were about to visit "+locker+" twice (visitingLockers="+visitingLockers+"), but locker is already deadlocked.",LogWriter.ERROR);
139                 }
140                 return locker;
141             }
142         } else {
143 // env.logWriter.newEntry(this,"sendLockMessage(): "+locker+" is deadlocked.",LogWriter.DEBUG2);
144
return locker;
145         }
146     }
147
148 }
149
Popular Tags