1990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson/* 2990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * Copyright (C) 2007 The Android Open Source Project 3990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * 4990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * you may not use this file except in compliance with the License. 6990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * You may obtain a copy of the License at 7990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * 8990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * 10990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * Unless required by applicable law or agreed to in writing, software 11990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * See the License for the specific language governing permissions and 14990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * limitations under the License. 15990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson */ 16990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson 17990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilsonpackage libcore.java.lang; 18990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson 19990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilsonimport junit.framework.TestCase; 20990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson 219ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamathimport java.util.concurrent.CountDownLatch; 229ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath 23990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilsonpublic class OldAndroidMonitorTest extends TestCase { 24990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson 25990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson public void testWaitArgumentsTest() throws Exception { 26990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson /* Try some valid arguments. These should all 27990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * return very quickly. 28990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson */ 29990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson try { 30990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson synchronized (this) { 31990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson /* millisecond version */ 32990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson wait(1); 33990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson wait(10); 34990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson 35990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson /* millisecond + nanosecond version */ 36990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson wait(0, 1); 37990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson wait(0, 999999); 38990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson wait(1, 1); 39990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson wait(1, 999999); 40990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 41990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } catch (InterruptedException ex) { 42990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson throw new RuntimeException("good Object.wait() interrupted", 43990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson ex); 44990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } catch (Exception ex) { 45990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson throw new RuntimeException("Unexpected exception when calling" + 46990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson "Object.wait() with good arguments", ex); 47990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 48990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson 49990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson /* Try some invalid arguments. 50990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson */ 51990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson boolean sawException = false; 52990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson try { 53990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson synchronized (this) { 54990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson wait(-1); 55990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 56990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } catch (InterruptedException ex) { 57990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson throw new RuntimeException("bad Object.wait() interrupted", ex); 58990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } catch (IllegalArgumentException ex) { 59990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson sawException = true; 60990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } catch (Exception ex) { 61990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson throw new RuntimeException("Unexpected exception when calling" + 62990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson "Object.wait() with bad arguments", ex); 63990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 64990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson if (!sawException) { 65990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson throw new RuntimeException("bad call to Object.wait() should " + 66990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson "have thrown IllegalArgumentException"); 67990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 68990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson 69990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson sawException = false; 70990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson try { 71990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson synchronized (this) { 72990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson wait(0, -1); 73990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 74990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } catch (InterruptedException ex) { 75990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson throw new RuntimeException("bad Object.wait() interrupted", ex); 76990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } catch (IllegalArgumentException ex) { 77990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson sawException = true; 78990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } catch (Exception ex) { 79990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson throw new RuntimeException("Unexpected exception when calling" + 80990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson "Object.wait() with bad arguments", ex); 81990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 82990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson if (!sawException) { 83990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson throw new RuntimeException("bad call to Object.wait() should " + 84990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson "have thrown IllegalArgumentException"); 85990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 86990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson 87990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson sawException = false; 88990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson try { 89990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson synchronized (this) { 90990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson /* The legal range of nanos is 0-999999. */ 91990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson wait(0, 1000000); 92990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 93990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } catch (InterruptedException ex) { 94990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson throw new RuntimeException("bad Object.wait() interrupted", ex); 95990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } catch (IllegalArgumentException ex) { 96990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson sawException = true; 97990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } catch (Exception ex) { 98990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson throw new RuntimeException("Unexpected exception when calling" + 99990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson "Object.wait() with bad arguments", ex); 100990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 101990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson if (!sawException) { 102990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson throw new RuntimeException("bad call to Object.wait() should " + 103990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson "have thrown IllegalArgumentException"); 104990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 105990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 106990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson 1079ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath /** 1089ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath * A thread that blocks forever on {@code wait()} until it's interrupted. 1099ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath */ 1109ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath static class Waiter extends Thread { 1119ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath private final Object lock; 1129ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath private final CountDownLatch cdl; 1139ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath private boolean wasInterrupted; 1149ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath 1159ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath public Waiter(Object lock, CountDownLatch cdl) { 1169ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath this.lock = lock; 1179ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath this.cdl = cdl; 1189ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath wasInterrupted = false; 1199ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath } 120990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson 1219ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath @Override 1229ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath public void run() { 1239ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath synchronized (lock) { 124990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson try { 1259ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath cdl.countDown(); 1269ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath while (true) { 1279ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath lock.wait(); 128990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 129990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } catch (InterruptedException ex) { 1309ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath wasInterrupted = true; 131990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 132990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 133990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 134990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson 1359ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath public boolean wasInterrupted() { 1369ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath synchronized (lock) { 1379ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath return wasInterrupted; 138990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 139990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 1409ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath } 141990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson 1429ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath public void testInterrupt() throws Exception { 1439ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath final Object lock = new Object(); 1449ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath final CountDownLatch cdl = new CountDownLatch(1); 1459ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath final Waiter waiter = new Waiter(lock, cdl); 146990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson 1479ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath waiter.start(); 148990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson 1499ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath // Wait for the "waiter" to start and acquire |lock| for the first time. 1509ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath try { 1519ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath cdl.await(); 1529ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath } catch (InterruptedException ie) { 1539ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath fail(); 1549ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath } 155990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson 1569ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath // Interrupt |waiter| after we acquire |lock|. This ensures that |waiter| is 1579ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath // currently blocked on a call to "wait". 1589ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath synchronized (lock) { 1599ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath waiter.interrupt(); 1609ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath } 161990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson 1629ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath // Wait for the waiter to complete. 1639ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath try { 1649ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath waiter.join(); 1659ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath } catch (InterruptedException ie) { 1669ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath fail(); 1679ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath } 168990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson 1699ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath // Assert than an InterruptedException was thrown. 1709ec2565efafc8aa11b118e011a7492d75eb6f28bNarayan Kamath assertTrue(waiter.wasInterrupted()); 171990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson } 172990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson} 173