xref: /illumos-gate/usr/src/cmd/dtrace/test/tst/common/java_api/src/TestDrop.java (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  *
26  * ident	"%Z%%M%	%I%	%E% SMI"
27  */
28 import java.util.*;
29 import java.util.concurrent.atomic.*;
30 import org.opensolaris.os.dtrace.*;
31 
32 /**
33  * Regression test for 6521523 aggregation drops can hang the Java
34  * DTrace API.
35  */
36 public class TestDrop {
37     static final String PROGRAM =
38 	    "fbt:genunix::entry { @[execname, pid] = count(); }";
39 
40     static AtomicLong consumerThreadID = new AtomicLong();
41     static AtomicLong getAggregateThreadID = new AtomicLong();
42     static AtomicBoolean done = new AtomicBoolean();
43     static int seconds;
44 
45     private static void
46     startTimer()
47     {
48 	if (seconds <= 0) {
49 	    return;
50 	}
51 
52 	final Timer timer = new Timer();
53 	timer.schedule(new TimerTask() {
54 	    public void run() {
55 		done.set(true);
56 		timer.cancel();
57 	    }
58 	}, seconds * 1000L);
59     }
60 
61     private static void
62     sampleAggregate(Consumer consumer) throws DTraceException
63     {
64 	while (consumer.isRunning() && !done.get()) {
65 	    try {
66 		Thread.currentThread().sleep(50);
67 	    } catch (InterruptedException e) {
68 	    }
69 
70 	    consumer.getAggregate(Collections. <String> emptySet());
71 	}
72     }
73 
74     private static void
75     startAggregateThread(final Consumer consumer)
76     {
77 	Runnable aggregateSampler = new Runnable() {
78 	    public void run() {
79 		Thread t = Thread.currentThread();
80 		getAggregateThreadID.set(t.getId());
81 		Throwable x = null;
82 		try {
83 		    sampleAggregate(consumer);
84 		} catch (Throwable e) {
85 		    x = e;
86 		}
87 
88 		if (Thread.holdsLock(LocalConsumer.class)) {
89 		    if (x != null) {
90 			x.printStackTrace();
91 		    }
92 		    System.out.println("Lock held");
93 		    System.exit(1);
94 		} else {
95 		    System.out.println("Lock released");
96 		    consumer.close(); // blocks if lock held
97 		}
98 	    }
99 	};
100 
101 	Thread t = new Thread(aggregateSampler, "Aggregate Sampler");
102 	t.start();
103     }
104 
105     static void
106     usage()
107     {
108 	System.err.println("usage: java TestDrop [ seconds ]");
109 	System.exit(2);
110     }
111 
112     public static void
113     main(String[] args)
114     {
115 	if (args.length == 1) {
116 	    try {
117 		seconds = Integer.parseInt(args[0]);
118 	    } catch (NumberFormatException e) {
119 		usage();
120 	    }
121 	} else if (args.length > 1) {
122 	    usage();
123 	}
124 
125 	final Consumer consumer = new LocalConsumer() {
126 	    protected Thread createThread() {
127 		Runnable worker = new Runnable() {
128 		    public void run() {
129 			Thread t = Thread.currentThread();
130 			consumerThreadID.set(t.getId());
131 			work();
132 		    }
133 		};
134 		Thread t = new Thread(worker);
135 		return t;
136 	    }
137 	};
138 
139 	consumer.addConsumerListener(new ConsumerAdapter() {
140 	    public void consumerStarted(ConsumerEvent e) {
141 		startAggregateThread(consumer);
142 		startTimer();
143 	    }
144 	    public void dataDropped(DropEvent e) throws ConsumerException {
145 		Thread t = Thread.currentThread();
146 		if (t.getId() == getAggregateThreadID.get()) {
147 		    Drop drop = e.getDrop();
148 		    throw new ConsumerException(drop.getDefaultMessage(),
149 			    drop);
150 		}
151 	    }
152 	});
153 
154 	try {
155 	    consumer.open();
156 	    consumer.setOption(Option.aggsize, Option.kb(1));
157 	    consumer.setOption(Option.aggrate, Option.millis(101));
158 	    consumer.compile(PROGRAM);
159 	    consumer.enable();
160 	    consumer.go(new ExceptionHandler() {
161 		public void handleException(Throwable e) {
162 		    e.printStackTrace();
163 		}
164 	    });
165 	} catch (DTraceException e) {
166 	    e.printStackTrace();
167 	}
168     }
169 }
170