1 /*******************************************************************************
2 * Copyright (c) 2009, 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 * Alexandre Montplaisir - Consolidate constructors, merge with TmfDataRequest
12 *******************************************************************************/
14 package org
.eclipse
.linuxtools
.tmf
.core
.request
;
16 import java
.util
.concurrent
.CountDownLatch
;
18 import org
.eclipse
.linuxtools
.internal
.tmf
.core
.TmfCoreTracer
;
19 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
20 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.TmfTimeRange
;
23 * TmfEventRequest's are used to obtain series of events from an event provider.
24 * Open ranges can be used, especially for continuous streaming.
26 * The request is processed asynchronously by a TmfEventProvider and, as events
27 * become available, handleData() is invoked synchronously for each one.
29 * The TmfEventProvider indicates that the request is completed by calling
30 * done(). The request can be cancelled at any time with cancel().
35 * TmfEventRequest request = new TmfEventRequest(DataType.class, range, startIndex, nbEvents, priority) {
37 * public void handleData(ITmfEvent event) {
38 * // do something with the event
41 * public void handleSuccess() {
42 * // callback for when the request completes successfully
45 * public void handleFailure() {
46 * // callback for when the request fails due to an error
49 * public void handleCancel() {
50 * // callback for when the request is cancelled via .cancel()
55 * eventProvider.sendRequest(request);
59 * TODO: Implement request failures (codes, etc...)
61 * @author Francois Chouinard
64 public abstract class TmfEventRequest
implements ITmfEventRequest
{
66 // ------------------------------------------------------------------------
68 // ------------------------------------------------------------------------
70 /** The request count for all the events */
71 public static final int ALL_DATA
= Integer
.MAX_VALUE
;
73 private static int fRequestNumber
= 0;
75 // ------------------------------------------------------------------------
77 // ------------------------------------------------------------------------
79 private final Class
<?
extends ITmfEvent
> fDataType
;
80 private final ExecutionType fExecType
;
82 /** A unique request ID */
83 private final int fRequestId
;
85 /** The requested events time range */
86 private final TmfTimeRange fRange
;
88 /** The index (rank) of the requested event */
89 protected long fIndex
;
91 /** The number of requested events (ALL_DATA for all) */
92 protected int fNbRequested
;
94 /** The number of reads so far */
97 private final CountDownLatch startedLatch
= new CountDownLatch(1);
98 private final CountDownLatch completedLatch
= new CountDownLatch(1);
100 private boolean fRequestRunning
;
101 private boolean fRequestCompleted
;
102 private boolean fRequestFailed
;
103 private boolean fRequestCanceled
;
105 // ------------------------------------------------------------------------
107 // ------------------------------------------------------------------------
110 * Request 'n' events of a given type, for the *whole* trace, at the given
114 * The requested data type.
116 * The index of the first event to retrieve. You can use '0' to
117 * start at the beginning of the trace.
119 * The number of events requested. You can use
120 * {@link TmfEventRequest#ALL_DATA} to indicate you want all
121 * events in the trace.
123 * The requested execution priority.
125 public TmfEventRequest(Class
<?
extends ITmfEvent
> dataType
,
128 ExecutionType priority
) {
129 this(dataType
, TmfTimeRange
.ETERNITY
, index
, nbRequested
, priority
);
133 * Request 'n' events of a given type, for the given time range, at the
137 * The requested data type.
139 * The time range of the requested events. You can use
140 * {@link TmfTimeRange#ETERNITY} to indicate you want to cover
143 * The index of the first event to retrieve. You can use '0' to
144 * start at the beginning of the trace.
146 * The number of events requested. You can use
147 * {@link TmfEventRequest#ALL_DATA} to indicate you want all
148 * events in the time range.
150 * The requested execution priority.
152 public TmfEventRequest(Class
<?
extends ITmfEvent
> dataType
,
156 ExecutionType priority
) {
158 fRequestId
= fRequestNumber
++;
159 fDataType
= dataType
;
161 fNbRequested
= nbRequested
;
162 fExecType
= priority
;
166 fRequestRunning
= false;
167 fRequestCompleted
= false;
168 fRequestFailed
= false;
169 fRequestCanceled
= false;
171 /* Setup the request tracing if it's enabled */
172 if (TmfCoreTracer
.isRequestTraced()) {
173 String type
= getClass().getName();
174 type
= type
.substring(type
.lastIndexOf('.') + 1);
175 @SuppressWarnings("nls")
176 String message
= "CREATED "
177 + (getExecType() == ExecutionType
.BACKGROUND ?
"(BG)" : "(FG)")
178 + " Type=" + type
+ " Index=" + getIndex() + " NbReq=" + getNbRequested()
179 + " Range=" + getRange()
180 + " DataType=" + getDataType().getSimpleName();
181 TmfCoreTracer
.traceRequest(this, message
);
186 * Resets the request counter (used for testing)
188 public static void reset() {
192 // ------------------------------------------------------------------------
194 // ------------------------------------------------------------------------
197 public int getRequestId() {
202 public long getIndex() {
207 public ExecutionType
getExecType() {
212 public int getNbRequested() {
217 public synchronized int getNbRead() {
222 public synchronized boolean isRunning() {
223 return fRequestRunning
;
227 public synchronized boolean isCompleted() {
228 return fRequestCompleted
;
232 public synchronized boolean isFailed() {
233 return fRequestFailed
;
237 public synchronized boolean isCancelled() {
238 return fRequestCanceled
;
242 public Class
<?
extends ITmfEvent
> getDataType() {
247 public TmfTimeRange
getRange() {
251 // ------------------------------------------------------------------------
253 // ------------------------------------------------------------------------
256 * This method is called by the event provider to set the index
257 * corresponding to the time range start time
260 * The start time index
262 protected void setIndex(int index
) {
267 public void setStartIndex(int index
) {
271 // ------------------------------------------------------------------------
273 // ------------------------------------------------------------------------
276 public void handleData(ITmfEvent event
) {
283 public void handleStarted() {
284 if (TmfCoreTracer
.isRequestTraced()) {
285 TmfCoreTracer
.traceRequest(this, "STARTED"); //$NON-NLS-1$
290 public void handleCompleted() {
291 boolean requestFailed
= false;
292 boolean requestCanceled
= false;
293 synchronized (this) {
294 requestFailed
= fRequestFailed
;
295 requestCanceled
= fRequestCanceled
;
300 } else if (requestCanceled
) {
305 if (TmfCoreTracer
.isRequestTraced()) {
306 TmfCoreTracer
.traceRequest(this, "COMPLETED (" + fNbRead
+ " events read)"); //$NON-NLS-1$ //$NON-NLS-2$
311 public void handleSuccess() {
312 if (TmfCoreTracer
.isRequestTraced()) {
313 TmfCoreTracer
.traceRequest(this, "SUCCEEDED"); //$NON-NLS-1$
318 public void handleFailure() {
319 if (TmfCoreTracer
.isRequestTraced()) {
320 TmfCoreTracer
.traceRequest(this, "FAILED"); //$NON-NLS-1$
325 public void handleCancel() {
326 if (TmfCoreTracer
.isRequestTraced()) {
327 TmfCoreTracer
.traceRequest(this, "CANCELLED"); //$NON-NLS-1$
332 * To suspend the client thread until the request starts (or is canceled).
334 * @throws InterruptedException
335 * If the thread was interrupted while waiting
337 public void waitForStart() throws InterruptedException
{
338 while (!fRequestRunning
) {
339 startedLatch
.await();
344 public void waitForCompletion() throws InterruptedException
{
345 while (!fRequestCompleted
) {
346 completedLatch
.await();
351 public void start() {
352 synchronized (this) {
353 fRequestRunning
= true;
356 startedLatch
.countDown();
361 synchronized (this) {
362 if (!fRequestCompleted
) {
363 fRequestRunning
= false;
364 fRequestCompleted
= true;
372 completedLatch
.countDown();
378 synchronized (this) {
379 fRequestFailed
= true;
385 public void cancel() {
386 synchronized (this) {
387 fRequestCanceled
= true;
392 // ------------------------------------------------------------------------
394 // ------------------------------------------------------------------------
397 // All requests have a unique id
398 public int hashCode() {
399 return getRequestId();
403 public boolean equals(Object other
) {
404 if (other
instanceof TmfEventRequest
) {
405 TmfEventRequest request
= (TmfEventRequest
) other
;
406 return request
.fDataType
== fDataType
407 && request
.fIndex
== fIndex
408 && request
.fNbRequested
== fNbRequested
409 && request
.fRange
.equals(fRange
);
415 public String
toString() {
416 String name
= getClass().getName();
417 int dot
= name
.lastIndexOf('.');
419 name
= name
.substring(dot
+ 1);
421 return '[' + name
+ '(' + getRequestId() + ',' + getDataType().getSimpleName() +
422 ',' + getExecType() + ',' + getRange() + ',' + getIndex() +
423 ',' + getNbRequested() + ")]"; //$NON-NLS-1$