X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=liblttng-ust-java-agent%2Fjava%2Flttng-ust-agent-common%2Forg%2Flttng%2Fust%2Fagent%2FAbstractLttngAgent.java;h=f8ad187bd99ce5e204a1a8d37dc4fb1fbb289936;hb=e7a87e50da7383e013bf7250464df0b838cffca2;hp=c3fc339bc628b09234e1ed41962f2197fb221b8f;hpb=3165c2f51abe3093f4c5512b499e33cb380b387d;p=lttng-ust.git diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/AbstractLttngAgent.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/AbstractLttngAgent.java index c3fc339b..f8ad187b 100644 --- a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/AbstractLttngAgent.java +++ b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/AbstractLttngAgent.java @@ -18,9 +18,8 @@ package org.lttng.ust.agent; +import java.util.Collection; import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; import java.util.Map; import java.util.NavigableMap; import java.util.Set; @@ -30,6 +29,8 @@ import java.util.concurrent.atomic.AtomicInteger; import org.lttng.ust.agent.client.ILttngTcpClientListener; import org.lttng.ust.agent.client.LttngTcpSessiondClient; +import org.lttng.ust.agent.filter.FilterChangeNotifier; +import org.lttng.ust.agent.session.EventRule; /** * Base implementation of a {@link ILttngAgent}. @@ -55,7 +56,7 @@ public abstract class AbstractLttngAgent * falls to 0, this means we can avoid sending log events through JNI * because nobody wants them. * - * It uses a concurrent hash set", so that the {@link #isEventEnabled} and + * It uses a concurrent hash map, so that the {@link #isEventEnabled} and * read methods do not need to take a synchronization lock. */ private final Map enabledEvents = new ConcurrentHashMap(); @@ -74,6 +75,19 @@ public abstract class AbstractLttngAgent /** Number of sessions currently enabling the wildcard "*" event */ private final AtomicInteger enabledWildcards = new AtomicInteger(0); + /** + * The application contexts currently enabled in the tracing sessions. + * + * It is first indexed by context retriever, then by context name. This + * allows to efficiently query all the contexts for a given retriever. + * + * Works similarly as {@link #enabledEvents}, but for app contexts (and with + * an extra degree of indexing). + * + * TODO Could be changed to a Guava Table once/if we start using it. + */ + private final Map> enabledAppContexts = new ConcurrentHashMap>(); + /** Tracing domain. Defined by the sub-classes via the constructor. */ private final Domain domain; @@ -184,28 +198,36 @@ public abstract class AbstractLttngAgent enabledEventPrefixes.clear(); enabledWildcards.set(0); - initialized = false; + enabledAppContexts.clear(); + initialized = false; } @Override - public boolean eventEnabled(String eventName) { + public boolean eventEnabled(EventRule eventRule) { + /* Notify the filter change manager of the command */ + FilterChangeNotifier.getInstance().addEventRule(eventRule); + + String eventName = eventRule.getEventName(); + if (eventName.equals(WILDCARD)) { enabledWildcards.incrementAndGet(); return true; } - if (eventName.endsWith(WILDCARD)) { /* Strip the "*" from the name. */ String prefix = eventName.substring(0, eventName.length() - 1); - return incrementEventCount(prefix, enabledEventPrefixes); + return incrementRefCount(prefix, enabledEventPrefixes); } - return incrementEventCount(eventName, enabledEvents); + return incrementRefCount(eventName, enabledEvents); } @Override public boolean eventDisabled(String eventName) { + /* Notify the filter change manager of the command */ + FilterChangeNotifier.getInstance().removeEventRules(eventName); + if (eventName.equals(WILDCARD)) { int newCount = enabledWildcards.decrementAndGet(); if (newCount < 0) { @@ -219,26 +241,52 @@ public abstract class AbstractLttngAgent if (eventName.endsWith(WILDCARD)) { /* Strip the "*" from the name. */ String prefix = eventName.substring(0, eventName.length() - 1); - return decrementEventCount(prefix, enabledEventPrefixes); + return decrementRefCount(prefix, enabledEventPrefixes); } - return decrementEventCount(eventName, enabledEvents); + return decrementRefCount(eventName, enabledEvents); } @Override - public Iterable listEnabledEvents() { - List events = new LinkedList(); + public boolean appContextEnabled(String contextRetrieverName, String contextName) { + synchronized (enabledAppContexts) { + Map retrieverMap = enabledAppContexts.get(contextRetrieverName); + if (retrieverMap == null) { + /* There is no submap for this retriever, let's create one. */ + retrieverMap = new ConcurrentHashMap(); + enabledAppContexts.put(contextRetrieverName, retrieverMap); + } - if (enabledWildcards.get() > 0) { - events.add(WILDCARD); + return incrementRefCount(contextName, retrieverMap); } - for (String prefix : enabledEventPrefixes.keySet()) { - events.add(new String(prefix + WILDCARD)); + } + + @Override + public boolean appContextDisabled(String contextRetrieverName, String contextName) { + synchronized (enabledAppContexts) { + Map retrieverMap = enabledAppContexts.get(contextRetrieverName); + if (retrieverMap == null) { + /* There was no submap for this retriever, invalid command? */ + return false; + } + + boolean ret = decrementRefCount(contextName, retrieverMap); + + /* If the submap is now empty we can remove it from the main map. */ + if (retrieverMap.isEmpty()) { + enabledAppContexts.remove(contextRetrieverName); + } + + return ret; } - events.addAll(enabledEvents.keySet()); - return events; } + /* + * Implementation of this method is domain-specific. + */ + @Override + public abstract Collection listAvailableEvents(); + @Override public boolean isEventEnabled(String eventName) { /* If at least one session enabled the "*" wildcard, send the event */ @@ -260,12 +308,17 @@ public abstract class AbstractLttngAgent return false; } - private static boolean incrementEventCount(String eventName, Map eventMap) { - synchronized (eventMap) { - Integer count = eventMap.get(eventName); + @Override + public Collection>> getEnabledAppContexts() { + return enabledAppContexts.entrySet(); + } + + private static boolean incrementRefCount(String key, Map refCountMap) { + synchronized (refCountMap) { + Integer count = refCountMap.get(key); if (count == null) { /* This is the first instance of this event being enabled */ - eventMap.put(eventName, Integer.valueOf(1)); + refCountMap.put(key, Integer.valueOf(1)); return true; } if (count.intValue() <= 0) { @@ -273,14 +326,14 @@ public abstract class AbstractLttngAgent throw new IllegalStateException(); } /* The event was already enabled, increment its refcount */ - eventMap.put(eventName, Integer.valueOf(count.intValue() + 1)); + refCountMap.put(key, Integer.valueOf(count.intValue() + 1)); return true; } } - private static boolean decrementEventCount(String eventName, Map eventMap) { - synchronized (eventMap) { - Integer count = eventMap.get(eventName); + private static boolean decrementRefCount(String key, Map refCountMap) { + synchronized (refCountMap) { + Integer count = refCountMap.get(key); if (count == null || count.intValue() <= 0) { /* * The sessiond asked us to disable an event that was not @@ -293,14 +346,14 @@ public abstract class AbstractLttngAgent * This is the last instance of this event being disabled, * remove it from the map so that we stop sending it. */ - eventMap.remove(eventName); + refCountMap.remove(key); return true; } /* * Other sessions are still looking for this event, simply decrement * its refcount. */ - eventMap.put(eventName, Integer.valueOf(count.intValue() - 1)); + refCountMap.put(key, Integer.valueOf(count.intValue() - 1)); return true; } }