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