tmf: Move plugins to the Trace Compass namespace
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.core / src / org / eclipse / linuxtools / internal / tmf / core / component / TmfEventThread.java
1 /*******************************************************************************
2 * Copyright (c) 2012, 2013 Ericsson
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
11 * Bernd Hufmann - Update handling of suspend and resume
12 *******************************************************************************/
13
14 package org.eclipse.linuxtools.internal.tmf.core.component;
15
16 import org.eclipse.linuxtools.internal.tmf.core.Activator;
17 import org.eclipse.linuxtools.internal.tmf.core.TmfCoreTracer;
18 import org.eclipse.linuxtools.tmf.core.component.ITmfEventProvider;
19 import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider;
20 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
21 import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest;
22 import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest.ExecutionType;
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 */
41 private final TmfEventProvider fProvider;
42
43 /**
44 * The wrapped event request
45 */
46 private final ITmfEventRequest fRequest;
47
48 /**
49 * The request execution priority
50 */
51 private final ExecutionType fExecType;
52
53 /**
54 * The wrapped thread (if applicable)
55 */
56 private final TmfEventThread fThread;
57
58 /**
59 * The thread execution state
60 */
61 private volatile boolean isCompleted = false;
62
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;
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 */
79 public TmfEventThread(TmfEventProvider provider, ITmfEventRequest request) {
80 assert provider != null;
81 assert request != null;
82 fProvider = provider;
83 fRequest = request;
84 fExecType = request.getExecType();
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 */
114 public ITmfEventProvider getProvider() {
115 return fProvider;
116 }
117
118 /**
119 * @return The event request
120 */
121 public ITmfEventRequest getRequest() {
122 return fRequest;
123 }
124
125 /**
126 * @return The request execution priority
127 */
128 public ExecutionType getExecType() {
129 return fExecType;
130 }
131
132 /**
133 * @return The request execution state
134 */
135 public boolean isRunning() {
136 return fRequest.isRunning() && !isPaused();
137 }
138
139 /**
140 * @return The request execution state
141 */
142 public boolean isPaused() {
143 return fIsPaused;
144 }
145
146 /**
147 * @return The request execution state
148 */
149 public boolean isCompleted() {
150 return isCompleted;
151 }
152
153 // ------------------------------------------------------------------------
154 // Runnable
155 // ------------------------------------------------------------------------
156
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();
164 int nbRequested = fRequest.getNbRequested();
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)) {
181
182 TmfCoreTracer.traceEvent(fProvider, fRequest, event);
183 if (fRequest.getDataType().isInstance(event)) {
184 fRequest.handleData(event);
185 }
186
187 // Pause execution if requested
188
189 while (fIsPaused) {
190 synchronized (fSynchObject) {
191 try {
192 fSynchObject.wait();
193 } catch (InterruptedException e) {
194 // continue
195 }
196 }
197 }
198
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) {
214 Activator.logError("Error in " + fProvider.getName() + " handling " + fRequest, e); //$NON-NLS-1$ //$NON-NLS-2$
215 fRequest.fail();
216 }
217
218 // Cleanup
219 context.dispose();
220 }
221
222 // ------------------------------------------------------------------------
223 // Operations
224 // ------------------------------------------------------------------------
225
226 /**
227 * Suspend the thread
228 */
229 public void suspend() {
230 fIsPaused = true;
231 TmfCoreTracer.traceRequest(fRequest, "SUSPENDED"); //$NON-NLS-1$
232 }
233
234 /**
235 * Resume the thread
236 */
237 public void resume() {
238 fIsPaused = false;
239 synchronized (fSynchObject) {
240 fSynchObject.notifyAll();
241 }
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 }
253 }
This page took 0.041833 seconds and 5 git commands to generate.