]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AsyncMultiReadEntry.java
Trying to remove synchronization problems
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / AsyncMultiReadEntry.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 java.util.ArrayList;
15
16 import org.simantics.db.AsyncReadGraph;
17 import org.simantics.db.common.GraphSemaphore;
18 import org.simantics.db.exception.DatabaseException;
19 import org.simantics.db.impl.graph.ReadGraphImpl;
20 import org.simantics.db.procedure.AsyncMultiProcedure;
21 import org.simantics.db.request.AsyncMultiRead;
22 import org.simantics.db.request.RequestFlags;
23
24 final public class AsyncMultiReadEntry<T> extends CacheEntryBase<AsyncMultiProcedure<T>> {
25
26     protected AsyncMultiRead<T> request;
27     
28     AsyncMultiReadEntry(AsyncMultiRead<T> request) {
29         this.request = request;
30     }
31     
32     @Override
33     int makeHash() {
34         return request.hashCode();
35     }
36     
37     @Override
38     public Object getOriginalRequest() {
39         return request;
40     }
41     
42     @Override
43     public void discard() {
44         super.discard();
45         request = null;
46         setResult(null);
47     }
48     
49     final synchronized public void finish(AsyncReadGraph graph) {
50         
51         assert(isPending());
52
53         synchronized(this) {
54                 setReady();
55         }
56         
57     }
58
59     final synchronized public void except(AsyncReadGraph graph, Throwable t) {
60
61         assert(isPending());
62
63         synchronized(this) {
64                 except(t);
65         }
66         
67     }
68
69     @SuppressWarnings("unchecked")
70         final synchronized public void addOrSet(Object item) {
71
72         assert(isPending());
73         
74         ArrayList<T> value = (ArrayList<T>)getResult(); 
75         value.add((T)item);
76         
77     }
78     
79     @Override
80     public void clearResult(QuerySupport support) {
81         setResult(new ArrayList<T>());
82     }
83     
84     @Override
85     final public Query getQuery() {
86         
87         return new Query() {
88
89                         @Override
90                         public void recompute(ReadGraphImpl graph) {
91
92                                 try {
93
94                                         GraphSemaphore s = new GraphSemaphore(graph, 0);
95
96                                         request.perform(graph , new AsyncMultiProcedure<T>() {
97
98                                                 @Override
99                                                 public void execute(AsyncReadGraph graph, T result) {
100                                                         addOrSet(result);
101                                                 }
102
103                                                 public void finished(AsyncReadGraph graph) {
104                                                         finish(graph);
105                                                         s.release();
106                                                 };
107
108                                                 @Override
109                                                 public void exception(AsyncReadGraph graph, Throwable t) {
110                                                         except(t);
111                                                         s.release();
112                                                 }
113
114                                         });
115
116                                         s.waitFor(1);
117
118                                 } catch (Throwable t) {
119                                         
120                                         except(t);
121                                         
122                                 }
123                                 
124                         }
125
126                         @Override
127                         public void removeEntry(QueryProcessor processor) {
128                         processor.cache.remove(AsyncMultiReadEntry.this);
129                         }
130
131                         @Override
132                         public int type() {
133                                 return RequestFlags.INVALIDATE;
134                         }
135                         
136                         @Override
137                         public String toString() {
138                                 if(request == null) return "DISCARDED";
139                                 else return request.toString() + statusOrException;
140                         }
141                 
142         };
143         
144     }
145
146         @SuppressWarnings("unchecked")
147         @Override
148         public Object performFromCache(ReadGraphImpl graph, AsyncMultiProcedure<T> proc) {
149
150         if(isExcepted()) {
151
152             try {
153                 proc.exception(graph, (Throwable)getResult());
154             } catch (Throwable t) {
155                 t.printStackTrace();
156             }
157             
158             
159         } else {
160             
161             final ArrayList<T> values = (ArrayList<T>)getResult();
162             for(T value : values) {
163                 try {
164                     proc.execute(graph, value);
165                 } catch (Throwable t) {
166                     t.printStackTrace();
167                 }
168             }
169
170             try {
171                 proc.finished(graph);
172             } catch (Throwable t) {
173                 t.printStackTrace();
174             }
175
176         }
177                 
178                 return getResult();
179                 
180         }
181         
182         @Override
183         public String toString() {
184                 if(request == null) return "DISCARDED";
185                 else return request.toString() + statusOrException;
186         }
187
188         //@Override
189         public Object compute(ReadGraphImpl graph, AsyncMultiProcedure<T> procedure) throws DatabaseException {
190         return graph.processor.cache.performQuery(graph, request, this, procedure);
191         }
192
193 }