KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > otm > lock > wait > TimeoutStrategy


1 package org.apache.ojb.otm.lock.wait;
2
3 /* Copyright 2003-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 import java.util.HashMap JavaDoc;
19 import org.apache.ojb.otm.core.Transaction;
20 import org.apache.ojb.otm.lock.LockingException;
21 import org.apache.ojb.otm.lock.ObjectLock;
22
23 public class TimeoutStrategy implements LockWaitStrategy
24 {
25
26     /**
27      * Maps tx to the lock that tx waits for.
28      * Is used for deadlock detection
29      */

30     private static HashMap JavaDoc _waitsFor = new HashMap JavaDoc();
31
32     private long _timeout;
33
34     /**
35      * @param timeout the number of milliseconds to wait before throwing exception
36      */

37     public TimeoutStrategy(long timeout)
38     {
39         if (timeout <= 0)
40         {
41             throw new IllegalArgumentException JavaDoc("Illegal timeout value: " + timeout);
42         }
43         _timeout = timeout;
44     }
45
46     /**
47      * The default timeout is 30 seconds
48      */

49     public TimeoutStrategy()
50     {
51         this(30000);
52     }
53
54     /**
55     * @see org.apache.ojb.otm.lock.wait.LockWaitStrategy#waitForLock(ObjectLock, Transaction)
56     */

57     public void waitForLock(ObjectLock lock, Transaction tx)
58         throws LockingException
59     {
60         Transaction writerTx;
61         ObjectLock writerWaitsForLock;
62
63         // test for deadlock
64
writerTx = lock.getWriter();
65         while (writerTx != null)
66         {
67             writerWaitsForLock = (ObjectLock) _waitsFor.get(writerTx);
68             if (writerWaitsForLock == null)
69             {
70                 break;
71             }
72             writerTx = writerWaitsForLock.getWriter();
73             if (writerTx == null)
74             {
75                 break;
76             }
77             if (writerTx == tx)
78             {
79                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
80
81                 // deadlock detected.
82
// Now we traverse the cycle once more to provide more info
83
writerTx = lock.getWriter();
84                 sb.append(lock.getTargetIdentity());
85                 while (writerTx != tx)
86                 {
87                     writerWaitsForLock = (ObjectLock) _waitsFor.get(writerTx);
88                     sb.append(" -> ");
89                     sb.append(writerWaitsForLock.getTargetIdentity());
90                     writerTx = writerWaitsForLock.getWriter();
91                 }
92                 throw new DeadlockException(sb.toString());
93             }
94         }
95
96         // No deadlock detected, then wait the given timeout
97
_waitsFor.put(tx, lock);
98         try
99         {
100             long now = System.currentTimeMillis();
101             long deadline = System.currentTimeMillis() + _timeout;
102
103             do
104             {
105                 if (lock.getWriter() == null)
106                 {
107                     return;
108                 }
109
110                 try
111                 {
112                     long toSleep = Math.min(deadline - now, 1000);
113                     Thread.sleep(toSleep);
114                     now += toSleep;
115                 } catch (InterruptedException JavaDoc ex) {
116                     now = System.currentTimeMillis();
117                 }
118             }
119             while (now < deadline);
120
121             writerTx = lock.getWriter();
122
123             if (writerTx != null)
124             {
125                 throw new ConcurrentModificationException(
126                         "Object [id: " + lock.getTargetIdentity()
127                         + "] locked by Transaction " + writerTx);
128             }
129         }
130         finally
131         {
132             _waitsFor.remove(tx);
133         }
134     }
135 }
136
Popular Tags