]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AsyncReadEntry.java
Trying to remove synchronization problems
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / AsyncReadEntry.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.db.impl.query;
13
14 import org.simantics.db.AsyncReadGraph;
15 import org.simantics.db.common.GraphSemaphore;
16 import org.simantics.db.exception.DatabaseException;
17 import org.simantics.db.exception.RuntimeDatabaseException;
18 import org.simantics.db.impl.DebugPolicy;
19 import org.simantics.db.impl.graph.ReadGraphImpl;
20 import org.simantics.db.procedure.AsyncProcedure;
21 import org.simantics.db.request.AsyncRead;
22
23 final public class AsyncReadEntry<T> extends CacheEntryBase<AsyncProcedure<T>> implements AsyncProcedure<T> {
24
25     protected AsyncRead<T> request;
26
27     AsyncReadEntry(AsyncRead<T> request) {
28         this.request = request;
29         if (DebugPolicy.QUERY_STATE)
30             System.out.println("[QUERY STATE]: created " + this);
31     }
32
33     @Override
34     int makeHash() {
35         return request.hashCode();
36     }
37
38     @Override
39     public Object getOriginalRequest() {
40         return request;
41     }
42
43     @Override
44     public void discard() {
45         super.discard();
46         setResult(null);
47     }
48
49     public void except(AsyncReadGraph graph, Throwable t) {
50
51         assert (isPending());
52
53         synchronized (this) {
54             except(t);
55         }
56
57     }
58
59     @Override
60     final public Query getQuery() {
61
62         return new Query() {
63
64             @Override
65             public void recompute(ReadGraphImpl graph) {
66
67                 try {
68
69                     GraphSemaphore s = new GraphSemaphore(graph, 0);
70
71                     request.perform(graph, new AsyncProcedure<T>() {
72
73                         @Override
74                         public void execute(AsyncReadGraph graph, T result) {
75                             setResult(result);
76                             setReady();
77                             s.release();
78                         }
79
80                         @Override
81                         public void exception(AsyncReadGraph graph, Throwable t) {
82                             except(t);
83                             s.release();
84                         }
85
86                     });
87
88                     s.waitFor(1);
89
90                 } catch (Throwable t) {
91                     except(t);
92                 }
93
94             }
95
96             @Override
97             public void removeEntry(QueryProcessor qp) {
98                 qp.cache.remove(AsyncReadEntry.this);
99             }
100
101             @Override
102             public int type() {
103                 return request.getFlags();
104             }
105
106             @Override
107             public String toString() {
108                 if (request == null)
109                     return "DISCARDED";
110                 else if (isExcepted())
111                     return request.toString() + " " + getResult();
112                 else
113                     return request.toString() + " " + statusOrException;
114             }
115
116         };
117
118     }
119
120     @Override
121     public Object performFromCache(ReadGraphImpl graph, AsyncProcedure<T> proc) {
122
123         if (isExcepted()) {
124
125             try {
126                 proc.exception(graph, (Throwable) getResult());
127             } catch (Throwable t) {
128                 t.printStackTrace();
129             }
130
131         } else {
132
133             try {
134                 proc.execute(graph, (T) getResult());
135             } catch (Throwable t) {
136                 t.printStackTrace();
137             }
138
139         }
140
141         return getResult();
142
143     }
144
145     public static <T> void computeForEach(ReadGraphImpl parentGraph, AsyncRead<T> request, AsyncReadEntry<T> entry,
146             AsyncProcedure<T> procedure_) throws DatabaseException {
147
148         AsyncProcedure<T> procedure = entry != null ? entry : procedure_;
149
150         GraphSemaphore s = new GraphSemaphore(parentGraph, 0);
151
152         ReadGraphImpl queryGraph = parentGraph.withParent(entry);
153
154         request.perform(queryGraph, new AsyncProcedure<T>() {
155
156             @Override
157             public void execute(AsyncReadGraph returnGraph, T result) {
158                 try {
159                     procedure.execute(parentGraph, result);
160                 } catch (Throwable t) {
161                     t.printStackTrace();
162                 }
163                 s.release();
164             }
165
166             @Override
167             public void exception(AsyncReadGraph returnGraph, Throwable t) {
168                 try {
169                     procedure.exception(parentGraph, t);
170                 } catch (Throwable t2) {
171                     t2.printStackTrace();
172                 }
173                 s.release();
174             }
175
176             @Override
177             public String toString() {
178                 return procedure.toString();
179             }
180
181         });
182
183         try {
184             s.waitFor(1);
185         } catch (InterruptedException e) {
186             throw new RuntimeDatabaseException(e);
187         }
188
189         if (entry != null)
190             entry.performFromCache(parentGraph, procedure_);
191
192     }
193
194     @Override
195     public String toString() {
196         if (isDiscarded())
197             return "DISCARDED " + request.toString();
198         else if (isExcepted())
199             return request.toString() + " " + getResult();
200         else
201             return request.toString() + " " + statusOrException;
202     }
203
204     @Override
205     public void execute(AsyncReadGraph graph, T result) {
206         setResult(result);
207         setReady();
208     }
209
210     @Override
211     public void exception(AsyncReadGraph graph, Throwable throwable) {
212         except(throwable);
213     }
214
215 }