fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * CDDL HEADER START
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * The contents of this file are subject to the terms of the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Common Development and Distribution License (the "License").
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * You may not use this file except in compliance with the License.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * See the License for the specific language governing permissions
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * and limitations under the License.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * When distributing Covered Code, include this CDDL HEADER in each
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * If applicable, add the following below this CDDL HEADER, with the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * fields enclosed by brackets "[]" replaced with your own identifying
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * information: Portions Copyright [yyyy] [name of copyright owner]
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * CDDL HEADER END
e77b06d21580f630e0a7c437495ab283d3672828tomee * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Use is subject to license terms.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Interface to the native DTrace library, each instance is a single
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * DTrace consumer.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @author Tom Erickson
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Implementation notes:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // libdtrace is *not* thread-safe. You cannot make multiple calls
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // into it simultaneously from different threads, even if those
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // threads are operating on different dtrace_hdl_t's. Calls to
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // libdtrace are synchronized on a global lock, LocalConsumer.class.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee static Logger logger = Logger.getLogger(LocalConsumer.class.getName());
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee // Needs to match the version in dtrace_jni.c
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private static final Option[] DEFAULT_OPTIONS = new Option[] {
52aacb450723e8271d37836e1b5861c2072a3981tomee // Undocumented configuration options
52aacb450723e8271d37836e1b5861c2072a3981tomee // Undocumented configuration options settable using
52aacb450723e8271d37836e1b5861c2072a3981tomee // java -Doption=value
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Last of all in case configuration options affect the loading
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // of the JNI table.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Native JNI interface (see lib/libdtrace_jni/dtrace_jni.c)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private static native void _checkVersion(int version);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private native void _open(OpenFlag[] flags) throws DTraceException;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private native Program _compileString(String program, String[] args)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private native Program.File _compileFile(String path, String[] args)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private native void _exec(Program program) throws DTraceException;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private native void _setOption(String option, String value)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private native long _getOption(String option) throws DTraceException;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private native void _consume() throws DTraceException;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private native Aggregate _getAggregate(AggregateSpec spec)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private native int _createProcess(String cmd) throws DTraceException;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private native void _grabProcess(int pid) throws DTraceException;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private native void _listProbes(List <ProbeDescription> probeList,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private native void _listProbeDetail(List <Probe> probeList,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Releases memory held in the JNI layer after dtrace_close() has
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // released critical system resources like file descriptors, and
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // calls to libdtrace are no longer needed (or possible).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Called by LogDistribution
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Cannot be static because the necessary dtrace handle is specific
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // to this Consumer.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private native String _lookupKernelFunction(Number address);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private native String _lookupUserFunction(int pid, Number address);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Undocumented configuration options
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private static native void _setMaximumConsumers(int max);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private int _handle = -1; // native C identifier (do not modify)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Per-consumer lock used in native code to prevent conflict between
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // the native consumer loop and the getAggregate() thread without
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // locking this LocalConsumer. A distinct per-consumer lock allows
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // the stop() method to be synchronized without causing deadlock
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // when the consumer loop grabs the per-consumer lock before
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // dtrace_work().
52aacb450723e8271d37836e1b5861c2072a3981tomee // stopLock is a synchronization lock used to ensure that the stop()
52aacb450723e8271d37836e1b5861c2072a3981tomee // method does not return until this consumer has actually stopped.
52aacb450723e8271d37836e1b5861c2072a3981tomee // Correct lock ordering is needed to ensure that listeners cannot
52aacb450723e8271d37836e1b5861c2072a3981tomee // deadlock this consumer:
52aacb450723e8271d37836e1b5861c2072a3981tomee // 1. stop() grabs the lock on this consumer before determining if
52aacb450723e8271d37836e1b5861c2072a3981tomee // this consumer is running (to ensure valid state).
52aacb450723e8271d37836e1b5861c2072a3981tomee // 2. Once stop() determines that this consumer is actually running,
52aacb450723e8271d37836e1b5861c2072a3981tomee // it releases the lock on this consumer. Failing to release the
52aacb450723e8271d37836e1b5861c2072a3981tomee // lock makes it possible for a ConsumerListener to deadlock this
52aacb450723e8271d37836e1b5861c2072a3981tomee // consumer by calling any synchronized LocalConcumer method
52aacb450723e8271d37836e1b5861c2072a3981tomee // (because the listener called by the worker thread prevents the
52aacb450723e8271d37836e1b5861c2072a3981tomee // worker thread from finishing while it waits for stop() to
52aacb450723e8271d37836e1b5861c2072a3981tomee // release the lock, which it will never do until the worker
52aacb450723e8271d37836e1b5861c2072a3981tomee // thread finishes).
52aacb450723e8271d37836e1b5861c2072a3981tomee // 3. stop() interrupts this consumer and grabs the stopLock, then
52aacb450723e8271d37836e1b5861c2072a3981tomee // waits on the stopLock for this consumer to stop (i.e. for the
52aacb450723e8271d37836e1b5861c2072a3981tomee // worker thread to finish).
52aacb450723e8271d37836e1b5861c2072a3981tomee // 4. The interrupted worker thread grabs the stopLock when it
52aacb450723e8271d37836e1b5861c2072a3981tomee // finishes so it can notify waiters on the stopLock (in this
52aacb450723e8271d37836e1b5861c2072a3981tomee // case the stop() method) that the worker thread is finished.
52aacb450723e8271d37836e1b5861c2072a3981tomee // The workEnded flag (whose access is protected by the
52aacb450723e8271d37836e1b5861c2072a3981tomee // stopLock), is used in case the interrupted worker thread
52aacb450723e8271d37836e1b5861c2072a3981tomee // finishes and grabs the stopLock before the stop() method does.
52aacb450723e8271d37836e1b5861c2072a3981tomee // Setting the flag in that case tells the stop() method it has
52aacb450723e8271d37836e1b5861c2072a3981tomee // nothing to wait for (otherwise stop() would wait forever,
52aacb450723e8271d37836e1b5861c2072a3981tomee // since there is no one left after the worker thread finishes to
52aacb450723e8271d37836e1b5861c2072a3981tomee // notify the stop() method to stop waiting).
52aacb450723e8271d37836e1b5861c2072a3981tomee // 5. The worker thread updates the state member to STOPPED and
52aacb450723e8271d37836e1b5861c2072a3981tomee // notifies listeners while it holds the stopLock and before it
52aacb450723e8271d37836e1b5861c2072a3981tomee // notifies waiters on the stopLock. This is to ensure that
52aacb450723e8271d37836e1b5861c2072a3981tomee // state has been updated to STOPPED and that listeners have
52aacb450723e8271d37836e1b5861c2072a3981tomee // executed consumerStopped() before the stop() method returns,
52aacb450723e8271d37836e1b5861c2072a3981tomee // to ensure valid state and in case the caller of stop() is
52aacb450723e8271d37836e1b5861c2072a3981tomee // relying on anything having been done by consumerStopped()
52aacb450723e8271d37836e1b5861c2072a3981tomee // before it proceeds to the next statement.
52aacb450723e8271d37836e1b5861c2072a3981tomee // 6. The worker thread notifies waiters on the stopLock before
52aacb450723e8271d37836e1b5861c2072a3981tomee // releasing it. stop() returns.
52aacb450723e8271d37836e1b5861c2072a3981tomee private static void
52aacb450723e8271d37836e1b5861c2072a3981tomee private static Integer
52aacb450723e8271d37836e1b5861c2072a3981tomee private static void
52aacb450723e8271d37836e1b5861c2072a3981tomee property = getIntegerProperty("JAVA_DTRACE_API_DEBUG");
52aacb450723e8271d37836e1b5861c2072a3981tomee property = getIntegerProperty("JAVA_DTRACE_MAX_CONSUMERS");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Creates a consumer that interacts with the native DTrace library
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * on the local system.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Called by native C code only
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private int
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Called by native C code only
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public synchronized void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new IllegalStateException("cannot reopen a closed consumer");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new IllegalStateException("consumer already open");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private synchronized void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case COMPILED: // caller may compile more than one program
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new IllegalStateException("go() already called");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public synchronized Program
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee compile(String program, String ... macroArgs) throws DTraceException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new NullPointerException("program string is null");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new NullPointerException("macro argument is null");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Could be an application with an embedded JVM, not
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // necessarily "java".
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee System.arraycopy(macroArgs, 0, argv, 1, macroArgs.length);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public synchronized Program
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee compile(File program, String ... macroArgs) throws DTraceException,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new NullPointerException("program file is null");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new NullPointerException("macro argument is null");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee System.arraycopy(macroArgs, 0, argv, 1, macroArgs.length);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private synchronized void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new IllegalArgumentException("program not compiled " +
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee "by this consumer");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public synchronized void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new IllegalStateException("no compiled program");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new IllegalStateException("go() already called");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Compile all programs if null
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Left to native code to throw IllegalArgumentException if the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // program is already enabled, since only the native code knows
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // the enabled state.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public synchronized void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee getProgramInfo(Program program) throws DTraceException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // The given program was compiled by this consumer, so we can
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // assert the following:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee assert ((state != State.INIT) && (state != State.OPEN));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public synchronized void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee setOption(String option, String value) throws DTraceException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new NullPointerException("option value is null");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case STARTED: // Some options can be set on a running consumer
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public synchronized long
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public final synchronized boolean
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return ((state != State.INIT) && (state != State.CLOSED));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public final synchronized boolean
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return false;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public final synchronized boolean
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public final synchronized boolean
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Called in the runnable target of the thread returned by {@link
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * #createThread()} to run this DTrace consumer.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @see #createThread()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee protected final void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (this) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // stop() was called after go() but before the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // consumer started
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return; // executes finally block before returning
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // We should not prevent other consumers from running
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // concurrently while this consumer blocks on the native
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // consumer loop. Instead, native code will acquire the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // LocalConsumer.class monitor as needed before calling
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // libdtrace functions.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee } catch (Throwable e) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee } finally {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (stopLock) {
52aacb450723e8271d37836e1b5861c2072a3981tomee // Notify listeners while holding stopLock to guarantee
52aacb450723e8271d37836e1b5861c2072a3981tomee // that listeners finish executing consumerStopped()
52aacb450723e8271d37836e1b5861c2072a3981tomee // before the stop() method returns.
52aacb450723e8271d37836e1b5861c2072a3981tomee synchronized (this) {
4d0eb50e691de4c20b1dd9976ad6839fede8a42dRichard PALO if (state == State.STOPPED || state == State.CLOSED) {
127bbe13a6d36580af6a8ded154f1201a6250772tomee // This consumer was stopped just after calling
127bbe13a6d36580af6a8ded154f1201a6250772tomee // go() but before starting (the premature return
127bbe13a6d36580af6a8ded154f1201a6250772tomee // case at the top of this work() method). It is
127bbe13a6d36580af6a8ded154f1201a6250772tomee // possible to call close() on a consumer that has
127bbe13a6d36580af6a8ded154f1201a6250772tomee // been stopped before starting. In that case the
127bbe13a6d36580af6a8ded154f1201a6250772tomee // premature return above still takes us here in the
127bbe13a6d36580af6a8ded154f1201a6250772tomee // finally clause, and we must not revert the CLOSED
127bbe13a6d36580af6a8ded154f1201a6250772tomee // state to STOPPED.
52aacb450723e8271d37836e1b5861c2072a3981tomee // Notify the stop() method to stop waiting
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Creates the background thread started by {@link #go()} to run
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * this consumer. Override this method if you need to set
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * non-default {@code Thread} options or create the thread in a
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * {@code ThreadGroup}. If you don't need to create the thread
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * yourself, set the desired options on {@code super.createThread()}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * before returning it. Otherwise, the {@code Runnable} target of
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the created thread must call {@link #work()} in order to run this
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * DTrace consumer. For example, to modify the default background
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * consumer thread:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * <pre><code>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * protected Thread
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * createThread()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Thread t = super.createThread();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * t.setPriority(Thread.MIN_PRIORITY);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * return t;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * </code></pre>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Or if you need to create your own thread:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * <pre></code>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * protected Thread
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * createThread()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Runnable target = new Runnable() {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * public void run() {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * String name = "Consumer " + UserApplication.sequence++;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Thread t = new Thread(UserApplication.threadGroup,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * target, name);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * return t;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * </code></pre>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Do not start the returned thread, otherwise {@code go()} will
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * throw an {@link IllegalThreadStateException} when it tries to
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * start the returned thread a second time.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public void run() {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @inheritDoc
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @throws IllegalThreadStateException if a subclass calls {@link
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Thread#start()} on the value of {@link #createThread()}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @see #createThread()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @inheritDoc
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @throws IllegalThreadStateException if a subclass calls {@link
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Thread#start()} on the value of {@link #createThread()}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @see #createThread()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public synchronized void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new IllegalStateException("no compiled program");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Throws IllegalStateException if not all compiled programs are
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // also enabled. Does not make any calls to libdtrace.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new IllegalStateException("go() already called");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new IllegalArgumentException("unknown state: " + state);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
382dbd461c555f1c7e304a961fd0d4458d958ca2tomee * @inheritDoc
382dbd461c555f1c7e304a961fd0d4458d958ca2tomee * @throws IllegalThreadStateException if attempting to {@code
382dbd461c555f1c7e304a961fd0d4458d958ca2tomee * stop()} a running consumer while holding the lock on that
52aacb450723e8271d37836e1b5861c2072a3981tomee public void
52aacb450723e8271d37836e1b5861c2072a3981tomee boolean running = false;
52aacb450723e8271d37836e1b5861c2072a3981tomee synchronized (this) {
52aacb450723e8271d37836e1b5861c2072a3981tomee synchronized (LocalConsumer.class) {
52aacb450723e8271d37836e1b5861c2072a3981tomee } catch (DTraceException e) {
52aacb450723e8271d37836e1b5861c2072a3981tomee // The work() thread that runs the native consumer
52aacb450723e8271d37836e1b5861c2072a3981tomee // loop may have terminated because of the exit()
52aacb450723e8271d37836e1b5861c2072a3981tomee // action in a DTrace program. In that case, a
52aacb450723e8271d37836e1b5861c2072a3981tomee // RuntimeException is inappropriate because there
52aacb450723e8271d37836e1b5861c2072a3981tomee // is no misuse of the API. Creating a new checked
52aacb450723e8271d37836e1b5861c2072a3981tomee // exception type to handle this case seems to offer
52aacb450723e8271d37836e1b5861c2072a3981tomee // no benefit for the trouble to the caller.
52aacb450723e8271d37836e1b5861c2072a3981tomee // Instead, the situation calls for stop() to be
52aacb450723e8271d37836e1b5861c2072a3981tomee // quietly tolerant.
52aacb450723e8271d37836e1b5861c2072a3981tomee "consumer already stopped");
52aacb450723e8271d37836e1b5861c2072a3981tomee throw new IllegalArgumentException("unknown state: " +
382dbd461c555f1c7e304a961fd0d4458d958ca2tomee throw new IllegalThreadStateException("The current " +
382dbd461c555f1c7e304a961fd0d4458d958ca2tomee "thread cannot stop this LocalConsumer while " +
382dbd461c555f1c7e304a961fd0d4458d958ca2tomee "holding the lock on this LocalConsumer");
52aacb450723e8271d37836e1b5861c2072a3981tomee // Calls no libdtrace methods, so no synchronization is
52aacb450723e8271d37836e1b5861c2072a3981tomee // needed. Sets a native flag that causes the consumer
52aacb450723e8271d37836e1b5861c2072a3981tomee // thread to exit the consumer loop and call native
52aacb450723e8271d37836e1b5861c2072a3981tomee // dtrace_stop() at the end of the current interval (after
52aacb450723e8271d37836e1b5861c2072a3981tomee // grabbing the global Consumer.class lock required for any
52aacb450723e8271d37836e1b5861c2072a3981tomee // libdtrace call).
52aacb450723e8271d37836e1b5861c2072a3981tomee synchronized (stopLock) {
52aacb450723e8271d37836e1b5861c2072a3981tomee // Wait for work() to set workEnded. If the work()
52aacb450723e8271d37836e1b5861c2072a3981tomee // thread got the stopLock first, then workEnded is
52aacb450723e8271d37836e1b5861c2072a3981tomee // already set.
52aacb450723e8271d37836e1b5861c2072a3981tomee // do nothing but re-check the condition for
43fb4b48d7d5ba4ce77cb215445844e34af5848btomee public synchronized void
43fb4b48d7d5ba4ce77cb215445844e34af5848btomee if ((state != State.INIT) && (state != State.CLOSED)) {
382dbd461c555f1c7e304a961fd0d4458d958ca2tomee * @inheritDoc
382dbd461c555f1c7e304a961fd0d4458d958ca2tomee * @throws IllegalThreadStateException if attempting to {@code
382dbd461c555f1c7e304a961fd0d4458d958ca2tomee * close()} a running consumer while holding the lock on that
382dbd461c555f1c7e304a961fd0d4458d958ca2tomee public void
382dbd461c555f1c7e304a961fd0d4458d958ca2tomee synchronized (this) {
382dbd461c555f1c7e304a961fd0d4458d958ca2tomee if ((state == State.INIT) || (state == State.CLOSED)) {
382dbd461c555f1c7e304a961fd0d4458d958ca2tomee // ignore (we don't have synchronized state access because
382dbd461c555f1c7e304a961fd0d4458d958ca2tomee // it is illegal to call stop() while holding the lock on
382dbd461c555f1c7e304a961fd0d4458d958ca2tomee // this consumer)
382dbd461c555f1c7e304a961fd0d4458d958ca2tomee synchronized (this) {
382dbd461c555f1c7e304a961fd0d4458d958ca2tomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // include all, clear none
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return getAggregate(null, Collections. <String> emptySet());
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private synchronized Aggregate
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee getAggregate(AggregateSpec spec) throws DTraceException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // It should be possible to request aggregation data after a
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // consumer has stopped but not after it has been closed.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Getting the aggregate is a time-consuming request that should not
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // prevent other consumers from running concurrently. Instead,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // native code will acquire the LocalConsumer.class monitor as
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // needed before calling libdtrace functions.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private synchronized void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private synchronized void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new IllegalStateException("go() already called");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public synchronized int
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public synchronized void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee listProbes(ProbeDescription filter) throws DTraceException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee listProbeDetail(ProbeDescription filter) throws DTraceException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee listProgramProbes(Program program) throws DTraceException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee listProgramProbeDetail(Program program) throws DTraceException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public synchronized String
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public synchronized String
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public synchronized String
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return _lookupUserFunction(pid, new Integer(address));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public synchronized String
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (LocalConsumer.class) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Called by native code.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee nextProbeData(ProbeData probeData) throws ConsumerException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Called by native code.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Called by native code.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee errorEncountered(Error error) throws ConsumerException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Called by native code.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee processStateChanged(ProcessState processState) throws ConsumerException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee fireProcessStateChanged(new ProcessEvent(this, processState));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee protected void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee fireDataReceived(DataEvent e) throws ConsumerException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Guaranteed to return a non-null array
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Process the listeners last to first, notifying
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // those that are interested in this event
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee protected void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Guaranteed to return a non-null array
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Process the listeners last to first, notifying
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // those that are interested in this event
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee protected void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee fireErrorEncountered(ErrorEvent e) throws ConsumerException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Guaranteed to return a non-null array
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Process the listeners last to first, notifying
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // those that are interested in this event
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee ((ConsumerListener)listeners[i + 1]).errorEncountered(e);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee protected void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee fireProcessStateChanged(ProcessEvent e) throws ConsumerException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Guaranteed to return a non-null array
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Process the listeners last to first, notifying
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // those that are interested in this event
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee ((ConsumerListener)listeners[i + 1]).processStateChanged(e);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee protected void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Guaranteed to return a non-null array
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Process the listeners last to first, notifying
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // those that are interested in this event
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee ((ConsumerListener)listeners[i + 1]).consumerStarted(e);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee protected void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Guaranteed to return a non-null array
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Process the listeners last to first, notifying
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // those that are interested in this event
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee ((ConsumerListener)listeners[i + 1]).consumerStopped(e);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Called by native code
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee fireIntervalBegan(new ConsumerEvent(this, System.nanoTime()));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee protected void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Guaranteed to return a non-null array
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Process the listeners last to first, notifying
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // those that are interested in this event
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee ((ConsumerListener)listeners[i + 1]).intervalBegan(e);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Called by native code
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee fireIntervalEnded(new ConsumerEvent(this, System.nanoTime()));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee protected void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Guaranteed to return a non-null array
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Process the listeners last to first, notifying
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // those that are interested in this event
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee ((ConsumerListener)listeners[i + 1]).intervalEnded(e);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets a string representation of this consumer useful for logging
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * and not intended for display. The exact details of the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * representation are unspecified and subject to change, but the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * following format may be regarded as typical:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * <pre><code>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * class-name[property1 = value1, property2 = value2]
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * </code></pre>
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee StringBuilder buf = new StringBuilder(LocalConsumer.class.getName());
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee synchronized (this) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Ensures that the {@link #close()} method of this consumer has
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * been called before it is garbage-collected. The intended safety
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * net is weak because the JVM does not guarantee that an object
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * will be garbage-collected when it is no longer referenced. Users
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * of the API should call {@code close()} to ensure that all
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * resources associated with this consumer are reclaimed in a timely
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @see #close()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee protected void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return super.toString();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Uniquely identifies a consumer across systems so it is possible
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // to validate that an object such as a Program passed to a remote
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // client over a socket was created by this consumer and no other.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee static final long serialVersionUID = 2183165132305302834L;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // local identifier
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // remote identifier
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private String tag; // in case localHost not available
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public boolean
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (o == this) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return true;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (o instanceof Identifier) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return false;