Disable CTF/TMF unit tests that depend on external traces
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / statesystem / AbstractStateChangeInput.java
CommitLineData
79e0a1df
AM
1/*******************************************************************************
2 * Copyright (c) 2012 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 * Alexandre Montplaisir - Initial API and implementation
11 *******************************************************************************/
12
13package org.eclipse.linuxtools.tmf.core.statesystem;
14
15import java.util.concurrent.ArrayBlockingQueue;
16import java.util.concurrent.BlockingQueue;
17
6cfa0200 18import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEventFactory;
79e0a1df 19import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
faa38350 20import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
79e0a1df
AM
21import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
22import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
23
24
25/**
26 * Instead of using IStateChangeInput directly, one can extend this class, which
27 * defines a lot of the common functions of the state change input plugin.
28 *
29 * It will handle the state-system-processing in a separate thread, which is
30 * normally not a bad idea for traces of some size.
31 *
32 * processEvent() is replaced with eventHandle(), so that all the multi-thread
33 * logic is abstracted away.
34 *
35 * @author Alexandre Montplaisir
36 * @since 2.0
37 */
38public abstract class AbstractStateChangeInput implements IStateChangeInput {
39
40 private static final int DEFAULT_EVENTS_QUEUE_SIZE = 10000;
41
79e0a1df 42 private final ITmfTrace trace;
79044a66
AM
43 private final Class<? extends ITmfEvent> eventType;
44 private final BlockingQueue<ITmfEvent> eventsQueue;
79e0a1df
AM
45 private final Thread eventHandlerThread;
46
47 private boolean ssAssigned;
79e0a1df
AM
48 private ITmfEvent currentEvent;
49
6f4e8ec0
AM
50 /** State system in which to insert the state changes */
51 protected ITmfStateSystemBuilder ss;
52
79e0a1df
AM
53 /**
54 * Instantiate a new state provider plugin.
55 *
56 * @param trace
57 * The LTTng 2.0 kernel trace directory
79044a66
AM
58 * @param eventType
59 * The specific class for the event type that will be used within
60 * the subclass
71f2da63
AM
61 * @param id
62 * Name given to this state change input. Only used internally.
79e0a1df 63 */
71f2da63
AM
64 public AbstractStateChangeInput(ITmfTrace trace,
65 Class<? extends ITmfEvent> eventType, String id) {
79e0a1df 66 this.trace = trace;
79044a66
AM
67 this.eventType = eventType;
68 eventsQueue = new ArrayBlockingQueue<ITmfEvent>(DEFAULT_EVENTS_QUEUE_SIZE);
79044a66 69 ssAssigned = false;
71f2da63
AM
70
71 String id2 = (id == null ? "Unamed" : id); //$NON-NLS-1$
72 eventHandlerThread = new Thread(new EventProcessor(), id2 + " Event Handler"); //$NON-NLS-1$
73
79e0a1df
AM
74 }
75
76 @Override
77 public ITmfTrace getTrace() {
78 return trace;
79 }
80
81 @Override
82 public long getStartTime() {
faa38350 83 return trace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
79e0a1df
AM
84 }
85
86 @Override
f1f86dfb 87 public void assignTargetStateSystem(ITmfStateSystemBuilder ssb) {
79e0a1df
AM
88 ss = ssb;
89 ssAssigned = true;
90 eventHandlerThread.start();
91 }
92
93 @Override
94 public void dispose() {
95 /* Insert a null event in the queue to stop the event handler's thread. */
96 try {
6cfa0200 97 eventsQueue.put(CtfTmfEventFactory.getNullEvent());
79e0a1df
AM
98 eventHandlerThread.join();
99 } catch (InterruptedException e) {
100 e.printStackTrace();
101 }
102 ssAssigned = false;
103 ss = null;
104 }
105
106 @Override
79044a66
AM
107 public final Class<? extends ITmfEvent> getExpectedEventType() {
108 return eventType;
109 }
110
111 @Override
112 public final void processEvent(ITmfEvent event) {
79e0a1df
AM
113 /* Make sure the target state system has been assigned */
114 if (!ssAssigned) {
115 System.err.println("Cannot process event without a target state system"); //$NON-NLS-1$
116 return;
117 }
118
119 /* Insert the event we're received into the events queue */
120 ITmfEvent curEvent = event;
121 try {
122 eventsQueue.put(curEvent);
123 } catch (InterruptedException e) {
124 e.printStackTrace();
125 }
126 }
127
79e0a1df
AM
128 /**
129 * This is the runner class for the second thread, which will take the
130 * events from the queue and pass them through the state system.
131 */
132 private class EventProcessor implements Runnable {
133
134 @Override
135 public void run() {
136 if (ss == null) {
137 System.err.println("Cannot run event manager without assigning a target state system first!"); //$NON-NLS-1$
138 return;
139 }
140 ITmfEvent event;
141
142 try {
143 event = eventsQueue.take();
144 while (event.getTimestamp().getValue() != -1) {
145 currentEvent = event;
79044a66
AM
146
147 /* Make sure this is an event the sub-class can process */
148 if (eventType.isInstance(event)) {
149 eventHandle(event);
150 }
79e0a1df
AM
151 event = eventsQueue.take();
152 }
153 /* We've received the last event, clean up */
154 closeStateSystem();
155 return;
156 } catch (InterruptedException e) {
157 /* We've been interrupted abnormally */
158 System.out.println("Event handler interrupted!"); //$NON-NLS-1$
159 e.printStackTrace();
160 }
161 }
162
163 private void closeStateSystem() {
164 /* Close the History system, if there is one */
165 if (currentEvent == null) {
166 return;
167 }
168 try {
faa38350 169 ss.closeHistory(currentEvent.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue());
79e0a1df
AM
170 } catch (TimeRangeException e) {
171 /*
172 * Since we're using currentEvent.getTimestamp, this shouldn't
173 * cause any problem
174 */
175 e.printStackTrace();
176 }
177 }
178 }
179
180 // ------------------------------------------------------------------------
181 // Abstract methods
182 // ------------------------------------------------------------------------
183
79e0a1df
AM
184 /**
185 * Handle the given event and send the appropriate state transitions into
186 * the the state system.
187 *
188 * This is basically the same thing as IStateChangeInput.processEvent(),
189 * except here processEvent() and eventHandle() are run in two different
190 * threads (and the AbstractStateChangeInput takes care of processEvent()
191 * already).
192 *
193 * @param event
194 * The event to process. If you need a specific event type, you
195 * should check for its instance right at the beginning.
196 */
197 protected abstract void eventHandle(ITmfEvent event);
198}
This page took 0.036671 seconds and 5 git commands to generate.