Commit | Line | Data |
---|---|---|
8a6ff07f | 1 | /******************************************************************************* |
31d786ef | 2 | * Copyright (c) 2013, 2016 École Polytechnique de Montréal |
8a6ff07f GB |
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 | |
8a6ff07f GB |
8 | *******************************************************************************/ |
9 | ||
2bdf0193 | 10 | package org.eclipse.tracecompass.tmf.tests.stubs.analysis; |
8a6ff07f | 11 | |
d0c7e4ba AM |
12 | import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; |
13 | ||
31d786ef GB |
14 | import java.util.concurrent.locks.Condition; |
15 | import java.util.concurrent.locks.Lock; | |
16 | import java.util.concurrent.locks.ReentrantLock; | |
17 | ||
d0c7e4ba | 18 | import org.eclipse.jdt.annotation.NonNull; |
31d786ef | 19 | import org.eclipse.jdt.annotation.Nullable; |
d0c7e4ba | 20 | import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder; |
e894a508 AM |
21 | import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; |
22 | import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException; | |
23 | import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue; | |
2bdf0193 | 24 | import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; |
2bdf0193 AM |
25 | import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider; |
26 | import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; | |
27 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | |
8a6ff07f GB |
28 | |
29 | /** | |
30 | * Stub test provider for test state system analysis module | |
31 | * | |
32 | * @author Geneviève Bastien | |
33 | */ | |
34 | public class TestStateSystemProvider extends AbstractTmfStateProvider { | |
35 | ||
31d786ef GB |
36 | /** |
37 | * This interface allows unit tests to provide only the event handling part | |
38 | * of the state provider, without having to extend the analysis and the | |
39 | * classes | |
40 | */ | |
41 | @FunctionalInterface | |
42 | public static interface TestStateProviderHandler { | |
43 | /** | |
44 | * Handles the event | |
45 | * | |
46 | * @param ss | |
47 | * The state system builder | |
48 | * @param event | |
49 | * The event to handler | |
50 | * @return <code>true</code> if everything went fine, or <code>false</code> to cancel | |
51 | */ | |
52 | boolean eventHandle(@NonNull ITmfStateSystemBuilder ss, ITmfEvent event); | |
53 | } | |
54 | ||
8a6ff07f | 55 | private static final int VERSION = 1; |
31d786ef GB |
56 | private static final String fString = "[]"; |
57 | private static int fCount = 0; | |
58 | private static final @NonNull TestStateProviderHandler DEFAULT_HANDLER = (ss, event) -> { | |
59 | /* Just need something to fill the state system */ | |
60 | if (fString.equals(event.getContent().getValue())) { | |
61 | try { | |
62 | int quarkId = ss.getQuarkAbsoluteAndAdd("String"); | |
63 | int quark = ss.getQuarkRelativeAndAdd(quarkId, fString); | |
64 | ss.modifyAttribute(event.getTimestamp().getValue(), TmfStateValue.newValueInt(fCount++), quark); | |
ed48dc75 | 65 | } catch (TimeRangeException | StateValueTypeException e) { |
31d786ef GB |
66 | |
67 | } | |
68 | } | |
69 | return true; | |
70 | }; | |
71 | private static @NonNull TestStateProviderHandler sfHandler = DEFAULT_HANDLER; | |
72 | ||
73 | /** | |
74 | * Set the event handler for the state provider | |
75 | * | |
76 | * @param handler | |
77 | * The class containing the event handler for this state provider | |
78 | */ | |
79 | public static void setEventHandler(TestStateProviderHandler handler) { | |
80 | if (handler == null) { | |
81 | sfHandler = DEFAULT_HANDLER; | |
82 | return; | |
83 | } | |
84 | sfHandler = handler; | |
85 | } | |
86 | ||
87 | private final Lock fLock = new ReentrantLock(); | |
88 | private @Nullable Condition fNextEventSignal = null; | |
8a6ff07f GB |
89 | |
90 | /** | |
91 | * Constructor | |
92 | * | |
93 | * @param trace | |
94 | * The LTTng 2.0 kernel trace directory | |
95 | */ | |
d0c7e4ba | 96 | public TestStateSystemProvider(@NonNull ITmfTrace trace) { |
e2bcc8a5 | 97 | super(trace, "Stub State System"); |
8a6ff07f GB |
98 | } |
99 | ||
100 | @Override | |
101 | public int getVersion() { | |
102 | return VERSION; | |
103 | } | |
104 | ||
105 | @Override | |
106 | public ITmfStateProvider getNewInstance() { | |
107 | return new TestStateSystemProvider(this.getTrace()); | |
108 | } | |
109 | ||
110 | @Override | |
111 | protected void eventHandle(ITmfEvent event) { | |
d0c7e4ba | 112 | ITmfStateSystemBuilder ss = checkNotNull(getStateSystemBuilder()); |
31d786ef GB |
113 | sfHandler.eventHandle(ss, event); |
114 | } | |
d0c7e4ba | 115 | |
31d786ef GB |
116 | @Override |
117 | public void processEvent(@NonNull ITmfEvent event) { | |
118 | fLock.lock(); | |
119 | try { | |
120 | Condition cond = fNextEventSignal; | |
121 | if (cond != null) { | |
122 | cond.await(); | |
123 | } | |
124 | } catch (InterruptedException e) { | |
125 | ||
126 | } finally { | |
127 | super.processEvent(event); | |
128 | fLock.unlock(); | |
129 | } | |
130 | } | |
131 | ||
132 | /** | |
133 | * Set the processing of event to be one event at a time instead of the | |
134 | * default behavior. It will block until the next call to | |
135 | * {@link #signalNextEvent()} method call. | |
136 | * | |
137 | * @param throttleEvent | |
138 | * Whether to wait for a signal to process the next event | |
139 | */ | |
140 | public void setThrottling(boolean throttleEvent) { | |
141 | fLock.lock(); | |
142 | try { | |
143 | if (throttleEvent) { | |
144 | Condition cond = fNextEventSignal; | |
145 | // If called for the first time, create a condition | |
146 | if (cond == null) { | |
147 | cond = fLock.newCondition(); | |
148 | fNextEventSignal = cond; | |
149 | } | |
150 | ||
151 | } else { | |
152 | Condition cond = fNextEventSignal; | |
153 | if (cond != null) { | |
154 | fNextEventSignal = null; | |
155 | cond.signalAll(); | |
156 | } | |
157 | } | |
158 | } finally { | |
159 | fLock.unlock(); | |
160 | } | |
161 | ||
162 | } | |
8a6ff07f | 163 | |
31d786ef GB |
164 | /** |
165 | * Signal for the next event to be processed. Calling this method makes | |
166 | * sense only if {@link #setThrottling(boolean)} has been set to true | |
167 | */ | |
168 | public void signalNextEvent() { | |
169 | fLock.lock(); | |
170 | try { | |
171 | Condition cond = fNextEventSignal; | |
172 | if (cond != null) { | |
173 | cond.signalAll(); | |
8a6ff07f | 174 | } |
31d786ef GB |
175 | } finally { |
176 | fLock.unlock(); | |
8a6ff07f GB |
177 | } |
178 | } | |
179 | ||
180 | } |