1 /*******************************************************************************
2 * Copyright (c) 2012, 2013 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 *******************************************************************************/
14 package org
.eclipse
.linuxtools
.internal
.tmf
.core
.component
;
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
;
26 * Provides the core event request processor. It also has support for suspending
27 * and resuming a request in a thread-safe manner.
29 * @author Francois Chouinard
32 public class TmfEventThread
implements Runnable
{
34 // ------------------------------------------------------------------------
36 // ------------------------------------------------------------------------
41 private final TmfEventProvider fProvider
;
44 * The wrapped event request
46 private final ITmfEventRequest fRequest
;
49 * The request execution priority
51 private final ExecutionType fExecType
;
54 * The wrapped thread (if applicable)
56 private final TmfEventThread fThread
;
59 * The thread execution state
61 private volatile boolean isCompleted
= false;
63 /** The synchronization object */
64 private final Object fSynchObject
= new Object();
66 /** The flag for suspending a thread */
67 private volatile boolean fIsPaused
= false;
69 // ------------------------------------------------------------------------
71 // ------------------------------------------------------------------------
76 * @param provider the event provider
77 * @param request the request to process
79 public TmfEventThread(TmfEventProvider provider
, ITmfEventRequest request
) {
80 assert provider
!= null;
81 assert request
!= null;
84 fExecType
= request
.getExecType();
91 * @param thread the thread to wrap
93 public TmfEventThread(TmfEventThread thread
) {
94 fProvider
= thread
.fProvider
;
95 fRequest
= thread
.fRequest
;
96 fExecType
= thread
.fExecType
;
100 // ------------------------------------------------------------------------
102 // ------------------------------------------------------------------------
105 * @return The wrapped thread
107 public TmfEventThread
getThread() {
112 * @return The event provider
114 public ITmfEventProvider
getProvider() {
119 * @return The event request
121 public ITmfEventRequest
getRequest() {
126 * @return The request execution priority
128 public ExecutionType
getExecType() {
133 * @return The request execution state
135 public boolean isRunning() {
136 return fRequest
.isRunning() && !isPaused();
140 * @return The request execution state
142 public boolean isPaused() {
147 * @return The request execution state
149 public boolean isCompleted() {
153 // ------------------------------------------------------------------------
155 // ------------------------------------------------------------------------
160 TmfCoreTracer
.traceRequest(fRequest
, "is being serviced by " + fProvider
.getName()); //$NON-NLS-1$
162 // Extract the generic information
164 int nbRequested
= fRequest
.getNbRequested();
168 // Initialize the execution
169 ITmfContext context
= fProvider
.armRequest(fRequest
);
170 if (context
== null) {
176 // Get the ordered events
177 ITmfEvent event
= fProvider
.getNext(context
);
178 TmfCoreTracer
.traceRequest(fRequest
, "read first event"); //$NON-NLS-1$
180 while (event
!= null && !fProvider
.isCompleted(fRequest
, event
, nbRead
)) {
182 TmfCoreTracer
.traceEvent(fProvider
, fRequest
, event
);
183 if (fRequest
.getDataType().isInstance(event
)) {
184 fRequest
.handleData(event
);
187 // Pause execution if requested
190 synchronized (fSynchObject
) {
193 } catch (InterruptedException e
) {
199 // To avoid an unnecessary read passed the last event requested
200 if (++nbRead
< nbRequested
) {
201 event
= fProvider
.getNext(context
);
207 if (fRequest
.isCancelled()) {
213 } catch (Exception e
) {
214 Activator
.logError("Error in " + fProvider
.getName() + " handling " + fRequest
, e
); //$NON-NLS-1$ //$NON-NLS-2$
222 // ------------------------------------------------------------------------
224 // ------------------------------------------------------------------------
229 public void suspend() {
231 TmfCoreTracer
.traceRequest(fRequest
, "SUSPENDED"); //$NON-NLS-1$
237 public void resume() {
239 synchronized (fSynchObject
) {
240 fSynchObject
.notifyAll();
242 TmfCoreTracer
.traceRequest(fRequest
, "RESUMED"); //$NON-NLS-1$
248 public void cancel() {
249 if (!fRequest
.isCompleted()) {