1 /*******************************************************************************
2 * Copyright (c) 2012, 2015 Ericsson
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
10 * Francois Chouinard - Initial API and implementation
11 * Bernd Hufmann - Update handling of suspend and resume
12 * Patrick Tasse - Exit early if request is cancelled
13 *******************************************************************************/
15 package org
.eclipse
.tracecompass
.internal
.tmf
.core
.component
;
17 import java
.util
.concurrent
.CountDownLatch
;
19 import org
.eclipse
.tracecompass
.internal
.tmf
.core
.Activator
;
20 import org
.eclipse
.tracecompass
.internal
.tmf
.core
.TmfCoreTracer
;
21 import org
.eclipse
.tracecompass
.tmf
.core
.component
.ITmfEventProvider
;
22 import org
.eclipse
.tracecompass
.tmf
.core
.component
.TmfEventProvider
;
23 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
24 import org
.eclipse
.tracecompass
.tmf
.core
.request
.ITmfEventRequest
;
25 import org
.eclipse
.tracecompass
.tmf
.core
.request
.ITmfEventRequest
.ExecutionType
;
26 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfContext
;
29 * Provides the core event request processor. It also has support for suspending
30 * and resuming a request in a thread-safe manner.
32 * @author Francois Chouinard
35 public class TmfEventThread
implements Runnable
{
37 // ------------------------------------------------------------------------
39 // ------------------------------------------------------------------------
44 private final TmfEventProvider fProvider
;
47 * The wrapped event request
49 private final ITmfEventRequest fRequest
;
52 * The request execution priority
54 private final ExecutionType fExecType
;
57 * The wrapped thread (if applicable)
59 private final TmfEventThread fThread
;
61 private volatile CountDownLatch fLatch
= new CountDownLatch(1);
64 * The thread execution state
66 private volatile boolean isCompleted
= false;
68 /** The flag for suspending a thread */
69 private volatile boolean fIsPaused
= false;
71 // ------------------------------------------------------------------------
73 // ------------------------------------------------------------------------
78 * @param provider the event provider
79 * @param request the request to process
81 public TmfEventThread(TmfEventProvider provider
, ITmfEventRequest request
) {
82 assert provider
!= null;
83 assert request
!= null;
86 fExecType
= request
.getExecType();
93 * @param thread the thread to wrap
95 public TmfEventThread(TmfEventThread thread
) {
96 fProvider
= thread
.fProvider
;
97 fRequest
= thread
.fRequest
;
98 fExecType
= thread
.fExecType
;
102 // ------------------------------------------------------------------------
104 // ------------------------------------------------------------------------
107 * @return The wrapped thread
109 public TmfEventThread
getThread() {
114 * @return The event provider
116 public ITmfEventProvider
getProvider() {
121 * @return The event request
123 public ITmfEventRequest
getRequest() {
128 * @return The request execution priority
130 public ExecutionType
getExecType() {
135 * @return The request execution state
137 public boolean isRunning() {
138 return fRequest
.isRunning() && !isPaused();
142 * @return The request execution state
144 public boolean isPaused() {
149 * @return The request execution state
151 public boolean isCompleted() {
155 // ------------------------------------------------------------------------
157 // ------------------------------------------------------------------------
162 TmfCoreTracer
.traceRequest(fRequest
.getRequestId(), "is being serviced by " + fProvider
.getName()); //$NON-NLS-1$
164 if (fRequest
.isCancelled()) {
169 // Extract the generic information
171 int nbRequested
= fRequest
.getNbRequested();
174 // Initialize the execution
175 ITmfContext context
= fProvider
.armRequest(fRequest
);
176 if (context
== null) {
183 // Get the ordered events
184 ITmfEvent event
= fProvider
.getNext(context
);
185 TmfCoreTracer
.traceRequest(fRequest
.getRequestId(), "read first event"); //$NON-NLS-1$
187 while (event
!= null && !fProvider
.isCompleted(fRequest
, event
, nbRead
)) {
189 TmfCoreTracer
.traceEvent(fProvider
, fRequest
, event
);
190 if (fRequest
.getDataType().isInstance(event
)) {
191 fRequest
.handleData(event
);
194 // Pause execution if requested
196 CountDownLatch latch
= fLatch
;
200 // To avoid an unnecessary read passed the last event requested
201 if (++nbRead
< nbRequested
) {
202 event
= fProvider
.getNext(context
);
208 if (fRequest
.isCancelled()) {
214 } catch (Exception e
) {
215 Activator
.logError("Error in " + fProvider
.getName() + " handling " + fRequest
, e
); //$NON-NLS-1$ //$NON-NLS-2$
224 // ------------------------------------------------------------------------
226 // ------------------------------------------------------------------------
231 public void suspend() {
233 TmfCoreTracer
.traceRequest(fRequest
.getRequestId(), "SUSPENDED"); //$NON-NLS-1$
239 public void resume() {
242 CountDownLatch oldLatch
= fLatch
;
243 fLatch
= new CountDownLatch(1);
244 oldLatch
.countDown();
246 TmfCoreTracer
.traceRequest(fRequest
.getRequestId(), "RESUMED"); //$NON-NLS-1$
252 public void cancel() {
253 if (!fRequest
.isCompleted()) {