xref: /illumos-gate/usr/src/cmd/dtrace/test/tst/common/java_api/src/TestDrop.java (revision edd580643f2cf1434e252cd7779e83182ea84945)
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 import java.util.*;
27 import java.util.concurrent.atomic.*;
28 import org.opensolaris.os.dtrace.*;
29 
30 /**
31  * Regression test for 6521523 aggregation drops can hang the Java
32  * DTrace API.
33  */
34 public class TestDrop {
35     static final String PROGRAM =
36 	    "fbt:genunix::entry { @[execname, pid] = count(); }";
37 
38     static AtomicLong consumerThreadID = new AtomicLong();
39     static AtomicLong getAggregateThreadID = new AtomicLong();
40     static AtomicBoolean done = new AtomicBoolean();
41     static int seconds;
42 
43     private static void
44     startTimer()
45     {
46 	if (seconds <= 0) {
47 	    return;
48 	}
49 
50 	final Timer timer = new Timer();
51 	timer.schedule(new TimerTask() {
52 	    public void run() {
53 		done.set(true);
54 		timer.cancel();
55 	    }
56 	}, seconds * 1000L);
57     }
58 
59     private static void
60     sampleAggregate(Consumer consumer) throws DTraceException
61     {
62 	while (consumer.isRunning() && !done.get()) {
63 	    try {
64 		Thread.sleep(50);
65 	    } catch (InterruptedException e) {
66 	    }
67 
68 	    consumer.getAggregate(Collections. <String> emptySet());
69 	}
70     }
71 
72     private static void
73     startAggregateThread(final Consumer consumer)
74     {
75 	Runnable aggregateSampler = new Runnable() {
76 	    public void run() {
77 		Thread t = Thread.currentThread();
78 		getAggregateThreadID.set(t.getId());
79 		Throwable x = null;
80 		try {
81 		    sampleAggregate(consumer);
82 		} catch (Throwable e) {
83 		    x = e;
84 		}
85 
86 		if (Thread.holdsLock(LocalConsumer.class)) {
87 		    if (x != null) {
88 			x.printStackTrace();
89 		    }
90 		    System.out.println("Lock held");
91 		    System.exit(1);
92 		} else {
93 		    System.out.println("Lock released");
94 		    consumer.close(); // blocks if lock held
95 		}
96 	    }
97 	};
98 
99 	Thread t = new Thread(aggregateSampler, "Aggregate Sampler");
100 	t.start();
101     }
102 
103     static void
104     usage()
105     {
106 	System.err.println("usage: java TestDrop [ seconds ]");
107 	System.exit(2);
108     }
109 
110     public static void
111     main(String[] args)
112     {
113 	if (args.length == 1) {
114 	    try {
115 		seconds = Integer.parseInt(args[0]);
116 	    } catch (NumberFormatException e) {
117 		usage();
118 	    }
119 	} else if (args.length > 1) {
120 	    usage();
121 	}
122 
123 	final Consumer consumer = new LocalConsumer() {
124 	    protected Thread createThread() {
125 		Runnable worker = new Runnable() {
126 		    public void run() {
127 			Thread t = Thread.currentThread();
128 			consumerThreadID.set(t.getId());
129 			work();
130 		    }
131 		};
132 		Thread t = new Thread(worker);
133 		return t;
134 	    }
135 	};
136 
137 	consumer.addConsumerListener(new ConsumerAdapter() {
138 	    public void consumerStarted(ConsumerEvent e) {
139 		startAggregateThread(consumer);
140 		startTimer();
141 	    }
142 	    public void dataDropped(DropEvent e) throws ConsumerException {
143 		Thread t = Thread.currentThread();
144 		if (t.getId() == getAggregateThreadID.get()) {
145 		    Drop drop = e.getDrop();
146 		    throw new ConsumerException(drop.getDefaultMessage(),
147 			    drop);
148 		}
149 	    }
150 	});
151 
152 	try {
153 	    consumer.open();
154 	    consumer.setOption(Option.aggsize, Option.kb(1));
155 	    consumer.setOption(Option.aggrate, Option.millis(101));
156 	    consumer.compile(PROGRAM);
157 	    consumer.enable();
158 	    consumer.go(new ExceptionHandler() {
159 		public void handleException(Throwable e) {
160 		    e.printStackTrace();
161 		}
162 	    });
163 	} catch (DTraceException e) {
164 	    e.printStackTrace();
165 	}
166     }
167 }
168