1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package art.test; 18 19 import java.util.concurrent.locks.ReentrantLock; 20 21 public class TestWatcher { 22 // Lock to synchronize access to the static state of this class. 23 private static final ReentrantLock lock = new ReentrantLock(); 24 private static volatile boolean criticalFailure = false; 25 private static boolean reportingEnabled = true; 26 private static boolean doingReport = false; 27 MonitorEnter()28 private static void MonitorEnter() { 29 lock.lock(); 30 } 31 MonitorExit()32 private static void MonitorExit() { 33 // Need to do this manually since we need to notify critical failure but would deadlock if 34 // waited for the unlock. 35 if (!lock.isHeldByCurrentThread()) { 36 NotifyCriticalFailure(); 37 throw new IllegalMonitorStateException("Locking error!"); 38 } else { 39 lock.unlock(); 40 } 41 } 42 43 // Stops reporting. Must be paired with an EnableReporting call. DisableReporting()44 public static void DisableReporting() { 45 MonitorEnter(); 46 reportingEnabled = false; 47 } 48 49 // Stops reporting. Must be paired with a DisableReporting call. EnableReporting()50 public static void EnableReporting() { 51 reportingEnabled = true; 52 MonitorExit(); 53 } 54 NotifyCriticalFailure()55 public static void NotifyCriticalFailure() { 56 criticalFailure = true; 57 } 58 NotifyConstructed(Object o)59 public static void NotifyConstructed(Object o) { 60 if (criticalFailure) { 61 // Something went very wrong. We are probably trying to report it so don't get in the way. 62 return; 63 } 64 MonitorEnter(); 65 // We could enter an infinite loop if println allocates (which it does) so we disable 66 // reporting while we are doing a report. Since we are synchronized we won't miss any 67 // allocations. 68 if (reportingEnabled && !doingReport) { 69 doingReport = true; 70 System.out.println("Object allocated of type '" + o.getClass().getName() + "'"); 71 doingReport = false; 72 } 73 MonitorExit(); 74 } 75 } 76