KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > perseus > concurrency > pessimistic > RWPri2RLock


1 /**
2  * Copyright (C) 2001-2002
3  * - France Telecom R&D
4  * - Laboratoire Logiciels, Systemes, Reseaux - UMR 5526, CNRS-INPG-UJF
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  * Release: 1.0
21  *
22  * Authors:
23  *
24  */

25
26 package org.objectweb.perseus.concurrency.pessimistic;
27
28 import org.objectweb.perseus.concurrency.api.ConcurrencyException;
29 import org.objectweb.perseus.concurrency.api.RolledBackConcurrencyException;
30 import org.objectweb.perseus.concurrency.lib.RWLockValue;
31 import org.objectweb.perseus.dependency.api.DependencyGraph;
32
33 import java.util.Set JavaDoc;
34 import java.util.HashSet JavaDoc;
35 import java.util.List JavaDoc;
36 import java.util.ArrayList JavaDoc;
37
38 /**
39  * A lock associated to an oid (see the "locks" map within the pessimistic
40  * concurrency manager).
41  * Provides "one writer/multiple readers" concurrency policy with priority to
42  * readers (there is a risk for starvation wrt writers).
43  * @author E. Bruneton, P. Dechamboux
44  */

45 public final class RWPri2RLock extends Lock {
46     /**
47      * The contexts that have a lock for the oid to which this object is
48      * associated.
49      */

50     protected Object JavaDoc writer = null;
51     /**
52      * The number of threads that wait for aquiring this lock.
53      */

54     int waiter = 0;
55     /**
56      * The contexts that have a read lock for the oid to which this object
57      * is associated.
58      */

59     protected Set JavaDoc readers = new HashSet JavaDoc();
60
61     public RWPri2RLock() {
62     }
63
64     public RWPri2RLock(Object JavaDoc hints, DependencyGraph dg) {
65         super(hints, dg);
66     }
67
68     /**
69      * Acquires this lock in read mode for the given context. This method
70      * blocks until the lock can be acquired in read mode by this context.
71      * @param ctxt a context.
72      */

73     public synchronized void readIntention(Object JavaDoc ctxt)
74             throws ConcurrencyException {
75         boolean ok;
76         do {
77             ok = writer == null || writer.equals(ctxt);
78             if (!ok) {
79                 waiter ++;
80                 Object JavaDoc w = writer;
81                 try {
82                     if (!dg.addVertex(ctxt, w)) {
83                         throw new RolledBackConcurrencyException("Deadlock");
84                     }
85                     wait();
86                 } catch (InterruptedException JavaDoc e) {
87                     throw new ConcurrencyException(
88                         "Waiting of a read intention has been interupted:", e);
89                 } finally {
90                     waiter --;
91                     dg.removeVertex(ctxt, w);
92                 }
93             }
94         } while (!ok);
95         reservations--;
96         readers.add(ctxt);
97 //TODO implements writeIntention
98
}
99
100     /**
101      * Acquires this lock in write mode for the given context. This method
102      * blocks until the lock can be acquired in write mode by this context.
103      * @param ctxt a context.
104      */

105     public synchronized void writeIntention(Object JavaDoc ctxt)
106             throws ConcurrencyException {
107         boolean ok;
108         do {
109             if (writer == null) {
110                 int r = readers.size();
111                 ok = r == 0 || (r == 1 && readers.contains(ctxt));
112             } else {
113                 ok = writer.equals(ctxt);
114             }
115             if (!ok) {
116                 List JavaDoc l = new ArrayList JavaDoc();
117                 if (writer == null) {
118                     l.addAll(readers);
119                 } else {
120                     l.add(writer);
121                 }
122                 waiter ++;
123                 try {
124                     for (int i = 0; i < l.size(); ++i) {
125                         if (!dg.addVertex(ctxt, l.get(i))) {
126                             throw new RolledBackConcurrencyException("Deadlock");
127                         }
128                     }
129                     wait();
130                 } catch (InterruptedException JavaDoc e) {
131                     throw new ConcurrencyException(
132                         "Waiting of a write intention has been interupted:", e);
133                 } finally {
134                     waiter --;
135                     for (int i = 0; i < l.size(); ++i) {
136                         dg.removeVertex(ctxt, l.get(i));
137                     }
138                 }
139             }
140         } while (!ok);
141         reservations--;
142         writer = ctxt;
143 //TODO implements writeIntention
144
}
145
146     /**
147      * Removes the given context from the reader and writer lists of this
148      * lock.
149      * @param ctxt a context
150      * @return true if the reader and writer list are empty, after the
151      * context has been removed from these lists. In such a case, this
152      * object can be removed from the 'locks' map.
153      */

154     public synchronized boolean close(Object JavaDoc ctxt) {
155         //TODO: wake up blocking threads working in the closed context
156
readers.remove(ctxt);
157         if (writer != null && writer.equals(ctxt)) {
158             writer = null;
159         }
160         boolean res = reservations == 0
161                 && waiter == 0 && readers.isEmpty() && writer == null;
162         if (!res) {
163             notifyAll();
164         }
165         return res;
166     }
167
168     public synchronized byte getMax() {
169         if (writer != null) return RWLockValue.WRITE;
170         if (!readers.isEmpty()) return RWLockValue.READ;
171         return RWLockValue.NOLOCK;
172     }
173
174 }
175
Popular Tags