KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > perseus > concurrency > optimistic > OptimisticConcurrencyManager


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.optimistic;
27
28 import org.objectweb.perseus.concurrency.lib.Semaphore;
29 import org.objectweb.perseus.concurrency.lib.TimeStamp;
30 import org.objectweb.perseus.concurrency.api.ConcurrencyException;
31 import org.objectweb.perseus.concurrency.api.ConcurrencyManager;
32 import org.objectweb.perseus.dependency.api.DependencyGraph;
33 import org.objectweb.fractal.api.control.BindingController;
34 import org.objectweb.util.monolog.api.Logger;
35
36 import java.util.HashMap JavaDoc;
37 import java.util.Iterator JavaDoc;
38 import java.util.Map JavaDoc;
39
40 /**
41  * @author E. Bruneton
42  */

43 public abstract class OptimisticConcurrencyManager
44         implements ConcurrencyManager, BindingController {
45
46     public final static String JavaDoc DEPENDENCY_GRAPH_BINDING = "dependency-graph";
47
48     private Semaphore sem;
49
50     protected Logger logger = null;
51
52     private DependencyGraph dg = null;
53
54     /**
55      * A map associating time stamps to all oids in all active contexts.
56      */

57     protected Map JavaDoc timeStamps;
58
59     public OptimisticConcurrencyManager() {
60         super();
61         sem = new Semaphore();
62         timeStamps = new HashMap JavaDoc();
63     }
64
65     /**
66      * @param ctx is the context using the resource
67      * @param resourceId is the resource identifier
68      * @param timeStamp is the TimeStamp instance matching the resource
69      * @param hints uses to give information on access
70      * @param isDirtyBefore indicates if the object was already dirty before
71      * the access.
72      * @param isWrite indicates if the access is a write access
73      * @return the resource state to use
74      * @throws ConcurrencyException it is not possible to create a State for
75      * this resource identifier. One reason can the unavailibity of the
76      * resource.
77      */

78     protected abstract Object JavaDoc getState(Object JavaDoc ctx,
79                                        Object JavaDoc resourceId,
80                                        TimeStamp timeStamp,
81                                        boolean isDirtyBefore,
82                                        boolean isWrite) throws ConcurrencyException;
83
84     //IMPLEMENTATION OF THE UserBindingControler INTERFACE //
85
//------------------------------------------------------//
86

87     public String JavaDoc[] listFc() {
88         return new String JavaDoc[] {DEPENDENCY_GRAPH_BINDING};
89     }
90
91     public Object JavaDoc lookupFc(String JavaDoc s) {
92         if (DEPENDENCY_GRAPH_BINDING.equals(s)) {
93             return dg;
94         }
95         return null;
96     }
97
98     public void bindFc(String JavaDoc s, Object JavaDoc o) {
99         if ("logger".equals(s)) {
100             logger = (Logger) o;
101         } else if (DEPENDENCY_GRAPH_BINDING.equals(s)) {
102             dg = (DependencyGraph) o;
103         }
104     }
105
106     public void unbindFc(String JavaDoc s) {
107         if (DEPENDENCY_GRAPH_BINDING.equals(s)) {
108             dg = null;
109         }
110     }
111
112     //IMPLEMENTATION OF THE ConcurrencyManager INTERFACE //
113
//---------------------------------------------------//
114

115     public void begin(Object JavaDoc ctx) {
116         // does nothing
117
}
118
119     public boolean validate(Object JavaDoc ctx) {
120 //TODO: system will blocked if caller of validate never calls finalize
121
//TODO: (e.g. the app crashes or is killed)
122
sem.P();
123         Iterator JavaDoc tss = timeStamps.values().iterator();
124         while (tss.hasNext()) {
125             TimeStamp timeStamp = (TimeStamp) tss.next();
126             if (!timeStamp.validate(ctx)) {
127                 return false;
128             }
129         }
130         tss = timeStamps.values().iterator();
131         while (tss.hasNext()) {
132             TimeStamp timeStamp = (TimeStamp) tss.next();
133             timeStamp.finalize(ctx);
134         }
135         return true;
136     }
137
138     public void finalize(Object JavaDoc ctx) {
139         freeLocks(ctx);
140     }
141     private void freeLocks(Object JavaDoc ctx) {
142         if (sem.getUser() != Thread.currentThread()) {
143             throw new RuntimeException JavaDoc("Bad use of the concurrency manager: the validate must be call before the finalize method");
144         }
145         try {
146             Iterator JavaDoc tsIt = timeStamps.values().iterator();
147             while (tsIt.hasNext()) {
148                 TimeStamp timeStamp = null;
149                 timeStamp = (TimeStamp) tsIt.next();
150                 if (timeStamp.close(ctx)) {
151                     closeTimeStamp(timeStamp, ctx);
152                     tsIt.remove();
153                 }
154             }
155 //TODO: system will blocked if caller of validate never calls finalize
156
//TODO: (e.g. the app crashes or is killed)
157
} finally {
158             sem.V();
159         }
160     }
161
162     public void closeTimeStamp(TimeStamp timeStamp, Object JavaDoc ctx) {
163     }
164     
165     public void abort(Object JavaDoc ctx) {
166         freeLocks(ctx);
167     }
168
169     protected Object JavaDoc getResourceId(Object JavaDoc object) {
170         return object;
171     }
172
173     /**
174      * @return the TimeStamp.
175      */

176     public Object JavaDoc readIntention(Object JavaDoc ctx, Object JavaDoc resource, Object JavaDoc thinLock)
177             throws ConcurrencyException {
178         Object JavaDoc resourceId = getResourceId(resource);
179         sem.P();
180         TimeStamp timeStamp = getTimeStamp(resourceId, null);
181         boolean isDirtyBefore = timeStamp.isDirty(ctx);
182         timeStamp.P();
183         timeStamp.readIntention(ctx);
184         sem.V();
185         try {
186             return getState(ctx, resource, timeStamp, isDirtyBefore, false);
187         } catch(ConcurrencyException e) {
188             removeUnavailableResource(ctx, resourceId, thinLock, timeStamp);
189             throw e;
190         } finally {
191             timeStamp.V();
192         }
193     }
194
195     /**
196      * @return the TimeStamp.
197      */

198     public Object JavaDoc writeIntention(Object JavaDoc ctx, Object JavaDoc resource, Object JavaDoc thinLock)
199             throws ConcurrencyException {
200         Object JavaDoc resourceId = getResourceId(resource);
201         sem.P();
202         TimeStamp timeStamp = getTimeStamp(resourceId, thinLock);
203         boolean isDirtyBefore = timeStamp.isDirty(ctx);
204         timeStamp.P();
205         timeStamp.writeIntention(ctx);
206         sem.V();
207         try {
208             return getState(ctx, resource, timeStamp, isDirtyBefore, true);
209         } catch(ConcurrencyException e) {
210             removeUnavailableResource(ctx, resourceId, thinLock, timeStamp);
211             throw e;
212         } finally {
213             timeStamp.V();
214         }
215     }
216
217     private void removeUnavailableResource(Object JavaDoc ctx,
218                                           Object JavaDoc resourceId,
219                                           Object JavaDoc thinLock,
220                                           TimeStamp timeStamp) {
221         //The instance does not exist in the data support, remove the lock
222
if (timeStamp.close(ctx)) {
223             timeStamp.V();
224             sem.P();
225             timeStamp.P();
226             if (timeStamp.close(ctx)) {
227                 timeStamps.remove(resourceId);
228             }
229             sem.V();
230         }
231     }
232
233     //OTHER METHODS //
234
//--------------//
235

236     /**
237      * Returns the lock associated to the given oid.
238      * @param oid an object identifier.
239      * @return the lock associated to the given oid.
240      */

241     private TimeStamp getTimeStamp(Object JavaDoc oid, Object JavaDoc lockHints) {
242         TimeStamp timeStamp = (TimeStamp) timeStamps.get(oid);
243         if (timeStamp == null) {
244             timeStamp = new TimeStamp(oid);
245             timeStamps.put(oid, timeStamp);
246         }
247         timeStamp.reserve();
248         return timeStamp;
249     }
250 }
251
Popular Tags