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