1 /*******************************************************************************
2 * Copyright (c) 2012 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 * Alexandre Montplaisir - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.core
.statesystem
;
15 import java
.util
.concurrent
.ArrayBlockingQueue
;
16 import java
.util
.concurrent
.BlockingQueue
;
18 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
19 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.TimeRangeException
;
20 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
24 * Instead of using IStateChangeInput directly, one can extend this class, which
25 * defines a lot of the common functions of the state change input plugin.
27 * It will handle the state-system-processing in a separate thread, which is
28 * normally not a bad idea for traces of some size.
30 * processEvent() is replaced with eventHandle(), so that all the multi-thread
31 * logic is abstracted away.
33 * @author Alexandre Montplaisir
36 public abstract class AbstractStateChangeInput
implements IStateChangeInput
{
38 private static final int DEFAULT_EVENTS_QUEUE_SIZE
= 10000;
40 private final ITmfTrace trace
;
41 private final Class
<?
extends ITmfEvent
> eventType
;
42 private final BlockingQueue
<ITmfEvent
> eventsQueue
;
43 private final Thread eventHandlerThread
;
45 private boolean ssAssigned
;
46 protected IStateSystemBuilder ss
;
47 private ITmfEvent currentEvent
;
50 * Instantiate a new state provider plugin.
53 * The LTTng 2.0 kernel trace directory
55 * The specific class for the event type that will be used within
58 public AbstractStateChangeInput(ITmfTrace trace
, Class
<?
extends ITmfEvent
> eventType
) {
60 this.eventType
= eventType
;
61 eventsQueue
= new ArrayBlockingQueue
<ITmfEvent
>(DEFAULT_EVENTS_QUEUE_SIZE
);
62 eventHandlerThread
= new Thread(new EventProcessor(), "CTF Kernel Event Handler"); //$NON-NLS-1$
67 public ITmfTrace
getTrace() {
72 public long getStartTime() {
73 return trace
.getStartTime().getValue();
77 public void assignTargetStateSystem(IStateSystemBuilder ssb
) {
80 eventHandlerThread
.start();
84 public void dispose() {
85 /* Insert a null event in the queue to stop the event handler's thread. */
87 eventsQueue
.put(org
.eclipse
.linuxtools
.tmf
.core
.ctfadaptor
.CtfTmfEvent
.getNullEvent());
88 eventHandlerThread
.join();
89 } catch (InterruptedException e
) {
97 public final Class
<?
extends ITmfEvent
> getExpectedEventType() {
102 public final void processEvent(ITmfEvent event
) {
103 /* Make sure the target state system has been assigned */
105 System
.err
.println("Cannot process event without a target state system"); //$NON-NLS-1$
109 /* Insert the event we're received into the events queue */
110 ITmfEvent curEvent
= event
;
112 eventsQueue
.put(curEvent
);
113 } catch (InterruptedException e
) {
119 * This is the runner class for the second thread, which will take the
120 * events from the queue and pass them through the state system.
122 private class EventProcessor
implements Runnable
{
127 System
.err
.println("Cannot run event manager without assigning a target state system first!"); //$NON-NLS-1$
133 event
= eventsQueue
.take();
134 while (event
.getTimestamp().getValue() != -1) {
135 currentEvent
= event
;
137 /* Make sure this is an event the sub-class can process */
138 if (eventType
.isInstance(event
)) {
141 event
= eventsQueue
.take();
143 /* We've received the last event, clean up */
146 } catch (InterruptedException e
) {
147 /* We've been interrupted abnormally */
148 System
.out
.println("Event handler interrupted!"); //$NON-NLS-1$
153 private void closeStateSystem() {
154 /* Close the History system, if there is one */
155 if (currentEvent
== null) {
159 ss
.closeHistory(currentEvent
.getTimestamp().getValue());
160 } catch (TimeRangeException e
) {
162 * Since we're using currentEvent.getTimestamp, this shouldn't
170 // ------------------------------------------------------------------------
172 // ------------------------------------------------------------------------
175 * Handle the given event and send the appropriate state transitions into
176 * the the state system.
178 * This is basically the same thing as IStateChangeInput.processEvent(),
179 * except here processEvent() and eventHandle() are run in two different
180 * threads (and the AbstractStateChangeInput takes care of processEvent()
184 * The event to process. If you need a specific event type, you
185 * should check for its instance right at the beginning.
187 protected abstract void eventHandle(ITmfEvent event
);