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