Fix for streaming and reconnection. Added standalone releng for lttng.
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / signal / TmfSignalManager.java
CommitLineData
8c8bf09f 1/*******************************************************************************
e31e01e8 2 * Copyright (c) 2009, 2010 Ericsson
8c8bf09f
ASL
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 * Francois Chouinard - Initial API and implementation
11 *******************************************************************************/
12
6c13869b 13package org.eclipse.linuxtools.tmf.core.signal;
8c8bf09f
ASL
14
15import java.lang.reflect.InvocationTargetException;
16import java.lang.reflect.Method;
17import java.util.ArrayList;
18import java.util.HashMap;
19import java.util.List;
20import java.util.Map;
21
6c13869b 22import org.eclipse.linuxtools.tmf.core.Tracer;
dc299841 23
8c8bf09f
ASL
24/**
25 * <b><u>TmfSignalHandler</u></b>
26 * <p>
8d2e2848
FC
27 * This class manages the set of signal listeners and the signals they are
28 * interested in. When a signal is broadcasted, the appropriate listeners
29 * signal handlers are invoked.
8c8bf09f
ASL
30 * <p>
31 */
32public class TmfSignalManager {
33
8d2e2848
FC
34 // The set of event listeners and their corresponding handler methods.
35 // Note: listeners could be restricted to ITmfComponents but there is no
e31e01e8
FC
36 // harm in letting anyone use this since it is not tied to anything but
37 // the signal data type.
8c8bf09f 38 static private Map<Object, Method[]> fListeners = new HashMap<Object, Method[]>();
d5c13688 39 static private Map<Object, Method[]> fVIPListeners = new HashMap<Object, Method[]>();
8c8bf09f 40
8d2e2848 41 // If requested, add universal signal tracer
e31e01e8 42 // TODO: Temporary solution: should be enabled/disabled dynamically
8f965dd5 43 private static boolean fTraceIsActive = false;
8d2e2848 44 private static TmfSignalTracer fSignalTracer;
82b08e62
FC
45 static {
46 if (fTraceIsActive) {
8d2e2848 47 fSignalTracer = TmfSignalTracer.getInstance();
e31e01e8 48 register(fSignalTracer);
82b08e62
FC
49 }
50 }
8c8bf09f 51
e31e01e8 52 public static synchronized void register(Object listener) {
8c8bf09f
ASL
53 Method[] methods = getSignalHandlerMethods(listener);
54 if (methods.length > 0)
82b08e62 55 fListeners.put(listener, methods);
8c8bf09f
ASL
56 }
57
d5c13688
FC
58 public static synchronized void registerVIP(Object listener) {
59 Method[] methods = getSignalHandlerMethods(listener);
60 if (methods.length > 0)
61 fVIPListeners.put(listener, methods);
62 }
63
e31e01e8 64 public static synchronized void deregister(Object listener) {
d5c13688
FC
65 fVIPListeners.remove(listener);
66 fListeners.remove(listener);
8c8bf09f
ASL
67 }
68
69 /**
8d2e2848
FC
70 * Returns the list of signal handlers in the listener. Signal handler name
71 * is irrelevant; only the annotation (@TmfSignalHandler) is important.
72 *
73 * @param listener
74 * @return
75 */
76 static private Method[] getSignalHandlerMethods(Object listener) {
77 List<Method> handlers = new ArrayList<Method>();
78 Method[] methods = listener.getClass().getMethods();
79 for (Method method : methods) {
80 if (method.isAnnotationPresent(TmfSignalHandler.class)) {
81 handlers.add(method);
82 }
83 }
84 return handlers.toArray(new Method[handlers.size()]);
85 }
86
87 /**
88 * Invokes the handling methods that listens to signals of a given type.
8c8bf09f
ASL
89 *
90 * The list of handlers is built on-the-fly to allow for the dynamic
91 * creation/deletion of signal handlers. Since the number of signal
92 * handlers shouldn't be too high, this is not a big performance issue
93 * to pay for the flexibility.
94 *
fc6ccf6f
FC
95 * For synchronization purposes, the signal is bracketed by two synch signals.
96 *
97 * @param signal the signal to dispatch
8c8bf09f 98 */
c1c69938 99 static int fSignalId = 0;
8d2e2848 100 static public synchronized void dispatchSignal(TmfSignal signal) {
1b70b6dc
PT
101 int signalId = fSignalId++;
102 sendSignal(new TmfStartSynchSignal(signalId));
103 signal.setReference(signalId);
fc6ccf6f 104 sendSignal(signal);
1b70b6dc 105 sendSignal(new TmfEndSynchSignal(signalId));
fc6ccf6f
FC
106 }
107
d5c13688
FC
108 static private void sendSignal(TmfSignal signal) {
109 sendSignal(fVIPListeners, signal);
110 sendSignal(fListeners, signal);
111 }
112
113 static private void sendSignal(Map<Object, Method[]> listeners, TmfSignal signal) {
114
115 if (Tracer.isSignalTraced()) Tracer.traceSignal(signal, "(start)"); //$NON-NLS-1$
116
117 // Build the list of listener methods that are registered for this signal
118 Class<?> signalClass = signal.getClass();
119 Map<Object, List<Method>> targets = new HashMap<Object, List<Method>>();
120 targets.clear();
121 for (Map.Entry<Object, Method[]> entry : listeners.entrySet()) {
122 List<Method> matchingMethods = new ArrayList<Method>();
123 for (Method method : entry.getValue()) {
124 if (method.getParameterTypes()[0].isAssignableFrom(signalClass)) {
125 matchingMethods.add(method);
126 }
127 }
128 if (!matchingMethods.isEmpty()) {
129 targets.put(entry.getKey(), matchingMethods);
130 }
131 }
132
133 // Call the signal handlers
134 for (Map.Entry<Object, List<Method>> entry : targets.entrySet()) {
135 for (Method method : entry.getValue()) {
136 try {
137 method.invoke(entry.getKey(), new Object[] { signal });
138 if (Tracer.isSignalTraced()) {
139 Object key = entry.getKey();
140 String hash = String.format("%1$08X", entry.getKey().hashCode()); //$NON-NLS-1$
141 String target = "[" + hash + "] " + key.getClass().getSimpleName() + ":" + method.getName(); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
142 Tracer.traceSignal(signal, target);
143 }
144 } catch (IllegalArgumentException e) {
145 } catch (IllegalAccessException e) {
146 } catch (InvocationTargetException e) {
147 }
148 }
149 }
150
151 if (Tracer.isSignalTraced()) Tracer.traceSignal(signal, "(end)"); //$NON-NLS-1$
152 }
dc299841 153
dc299841 154}
This page took 0.039063 seconds and 5 git commands to generate.