Commit | Line | Data |
---|---|---|
96b353c5 | 1 | /******************************************************************************* |
61759503 | 2 | * Copyright (c) 2012, 2013 Ericsson |
96b353c5 FC |
3 | * |
4 | * All rights reserved. This program and the accompanying materials are | |
5 | * made available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: | |
10 | * Francois Chouinard - Initial API and implementation | |
1938a079 | 11 | * Bernd Hufmann - Update handling of suspend and resume |
96b353c5 FC |
12 | *******************************************************************************/ |
13 | ||
14 | package org.eclipse.linuxtools.internal.tmf.core.component; | |
15 | ||
b518f27e | 16 | import org.eclipse.linuxtools.internal.tmf.core.Activator; |
96b353c5 | 17 | import org.eclipse.linuxtools.internal.tmf.core.TmfCoreTracer; |
fd3f1eff AM |
18 | import org.eclipse.linuxtools.tmf.core.component.ITmfEventProvider; |
19 | import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider; | |
96b353c5 | 20 | import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; |
fd3f1eff AM |
21 | import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; |
22 | import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest.ExecutionType; | |
96b353c5 FC |
23 | import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; |
24 | ||
25 | /** | |
26 | * Provides the core event request processor. It also has support for suspending | |
27 | * and resuming a request in a thread-safe manner. | |
28 | * | |
29 | * @author Francois Chouinard | |
30 | * @version 1.0 | |
31 | */ | |
32 | public class TmfEventThread implements Runnable { | |
33 | ||
34 | // ------------------------------------------------------------------------ | |
35 | // Attributes | |
36 | // ------------------------------------------------------------------------ | |
37 | ||
38 | /** | |
39 | * The event provider | |
40 | */ | |
fd3f1eff | 41 | private final TmfEventProvider fProvider; |
96b353c5 FC |
42 | |
43 | /** | |
44 | * The wrapped event request | |
45 | */ | |
fd3f1eff | 46 | private final ITmfEventRequest fRequest; |
96b353c5 FC |
47 | |
48 | /** | |
49 | * The request execution priority | |
50 | */ | |
5419a136 | 51 | private final ExecutionType fExecType; |
96b353c5 FC |
52 | |
53 | /** | |
54 | * The wrapped thread (if applicable) | |
55 | */ | |
56 | private final TmfEventThread fThread; | |
57 | ||
58 | /** | |
59 | * The thread execution state | |
60 | */ | |
96b353c5 FC |
61 | private volatile boolean isCompleted = false; |
62 | ||
1938a079 BH |
63 | /** The synchronization object */ |
64 | private final Object fSynchObject = new Object(); | |
65 | ||
66 | /** The flag for suspending a thread */ | |
67 | private volatile boolean fIsPaused = false; | |
96b353c5 FC |
68 | |
69 | // ------------------------------------------------------------------------ | |
70 | // Constructor | |
71 | // ------------------------------------------------------------------------ | |
72 | ||
73 | /** | |
74 | * Basic constructor | |
75 | * | |
76 | * @param provider the event provider | |
77 | * @param request the request to process | |
78 | */ | |
fd3f1eff | 79 | public TmfEventThread(TmfEventProvider provider, ITmfEventRequest request) { |
96b353c5 FC |
80 | assert provider != null; |
81 | assert request != null; | |
82 | fProvider = provider; | |
83 | fRequest = request; | |
5419a136 | 84 | fExecType = request.getExecType(); |
96b353c5 FC |
85 | fThread = null; |
86 | } | |
87 | ||
88 | /** | |
89 | * Wrapper constructor | |
90 | * | |
91 | * @param thread the thread to wrap | |
92 | */ | |
93 | public TmfEventThread(TmfEventThread thread) { | |
94 | fProvider = thread.fProvider; | |
95 | fRequest = thread.fRequest; | |
96 | fExecType = thread.fExecType; | |
97 | fThread = thread; | |
98 | } | |
99 | ||
100 | // ------------------------------------------------------------------------ | |
101 | // Getters | |
102 | // ------------------------------------------------------------------------ | |
103 | ||
104 | /** | |
105 | * @return The wrapped thread | |
106 | */ | |
107 | public TmfEventThread getThread() { | |
108 | return fThread; | |
109 | } | |
110 | ||
111 | /** | |
112 | * @return The event provider | |
113 | */ | |
fd3f1eff | 114 | public ITmfEventProvider getProvider() { |
96b353c5 FC |
115 | return fProvider; |
116 | } | |
117 | ||
118 | /** | |
119 | * @return The event request | |
120 | */ | |
fd3f1eff | 121 | public ITmfEventRequest getRequest() { |
96b353c5 FC |
122 | return fRequest; |
123 | } | |
124 | ||
125 | /** | |
126 | * @return The request execution priority | |
127 | */ | |
5419a136 | 128 | public ExecutionType getExecType() { |
96b353c5 FC |
129 | return fExecType; |
130 | } | |
131 | ||
132 | /** | |
133 | * @return The request execution state | |
134 | */ | |
135 | public boolean isRunning() { | |
306586b1 SD |
136 | return fRequest.isRunning() && !isPaused(); |
137 | } | |
138 | ||
139 | /** | |
140 | * @return The request execution state | |
141 | */ | |
1938a079 BH |
142 | public boolean isPaused() { |
143 | return fIsPaused; | |
96b353c5 FC |
144 | } |
145 | ||
146 | /** | |
147 | * @return The request execution state | |
148 | */ | |
149 | public boolean isCompleted() { | |
150 | return isCompleted; | |
151 | } | |
152 | ||
153 | // ------------------------------------------------------------------------ | |
154 | // Runnable | |
155 | // ------------------------------------------------------------------------ | |
156 | ||
96b353c5 FC |
157 | @Override |
158 | public void run() { | |
159 | ||
160 | TmfCoreTracer.traceRequest(fRequest, "is being serviced by " + fProvider.getName()); //$NON-NLS-1$ | |
161 | ||
162 | // Extract the generic information | |
163 | fRequest.start(); | |
5419a136 | 164 | int nbRequested = fRequest.getNbRequested(); |
96b353c5 FC |
165 | int nbRead = 0; |
166 | isCompleted = false; | |
167 | ||
168 | // Initialize the execution | |
169 | ITmfContext context = fProvider.armRequest(fRequest); | |
170 | if (context == null) { | |
171 | fRequest.cancel(); | |
172 | return; | |
173 | } | |
174 | ||
175 | try { | |
176 | // Get the ordered events | |
177 | ITmfEvent event = fProvider.getNext(context); | |
178 | TmfCoreTracer.traceRequest(fRequest, "read first event"); //$NON-NLS-1$ | |
179 | ||
180 | while (event != null && !fProvider.isCompleted(fRequest, event, nbRead)) { | |
96b353c5 FC |
181 | |
182 | TmfCoreTracer.traceEvent(fProvider, fRequest, event); | |
5419a136 AM |
183 | if (fRequest.getDataType().isInstance(event)) { |
184 | fRequest.handleData(event); | |
185 | } | |
96b353c5 | 186 | |
29d60c55 | 187 | // Pause execution if requested |
1938a079 BH |
188 | |
189 | while (fIsPaused) { | |
190 | synchronized (fSynchObject) { | |
191 | try { | |
192 | fSynchObject.wait(); | |
193 | } catch (InterruptedException e) { | |
194 | // continue | |
195 | } | |
196 | } | |
197 | } | |
29d60c55 | 198 | |
96b353c5 FC |
199 | // To avoid an unnecessary read passed the last event requested |
200 | if (++nbRead < nbRequested) { | |
201 | event = fProvider.getNext(context); | |
202 | } | |
203 | } | |
204 | ||
205 | isCompleted = true; | |
206 | ||
207 | if (fRequest.isCancelled()) { | |
208 | fRequest.cancel(); | |
209 | } else { | |
210 | fRequest.done(); | |
211 | } | |
212 | ||
213 | } catch (Exception e) { | |
b518f27e | 214 | Activator.logError("Error in " + fProvider.getName() + " handling " + fRequest, e); //$NON-NLS-1$ //$NON-NLS-2$ |
96b353c5 FC |
215 | fRequest.fail(); |
216 | } | |
217 | ||
218 | // Cleanup | |
219 | context.dispose(); | |
220 | } | |
221 | ||
222 | // ------------------------------------------------------------------------ | |
223 | // Operations | |
224 | // ------------------------------------------------------------------------ | |
225 | ||
226 | /** | |
227 | * Suspend the thread | |
228 | */ | |
1938a079 BH |
229 | public void suspend() { |
230 | fIsPaused = true; | |
96b353c5 FC |
231 | TmfCoreTracer.traceRequest(fRequest, "SUSPENDED"); //$NON-NLS-1$ |
232 | } | |
233 | ||
234 | /** | |
235 | * Resume the thread | |
236 | */ | |
1938a079 BH |
237 | public void resume() { |
238 | fIsPaused = false; | |
239 | synchronized (fSynchObject) { | |
240 | fSynchObject.notifyAll(); | |
241 | } | |
96b353c5 FC |
242 | TmfCoreTracer.traceRequest(fRequest, "RESUMED"); //$NON-NLS-1$ |
243 | } | |
244 | ||
245 | /** | |
246 | * Cancel the request | |
247 | */ | |
248 | public void cancel() { | |
249 | if (!fRequest.isCompleted()) { | |
250 | fRequest.cancel(); | |
251 | } | |
252 | } | |
96b353c5 | 253 | } |