1 /* 2 * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/WaitingThread.java $ 3 * $Revision: 649217 $ 4 * $Date: 2008-04-17 11:32:32 -0700 (Thu, 17 Apr 2008) $ 5 * 6 * ==================================================================== 7 * 8 * Licensed to the Apache Software Foundation (ASF) under one or more 9 * contributor license agreements. See the NOTICE file distributed with 10 * this work for additional information regarding copyright ownership. 11 * The ASF licenses this file to You under the Apache License, Version 2.0 12 * (the "License"); you may not use this file except in compliance with 13 * the License. You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, software 18 * distributed under the License is distributed on an "AS IS" BASIS, 19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 * See the License for the specific language governing permissions and 21 * limitations under the License. 22 * ==================================================================== 23 * 24 * This software consists of voluntary contributions made by many 25 * individuals on behalf of the Apache Software Foundation. For more 26 * information on the Apache Software Foundation, please see 27 * <http://www.apache.org/>. 28 * 29 */ 30 31 package org.apache.http.impl.conn.tsccm; 32 33 34 import java.util.Date; 35 import java.util.concurrent.locks.Condition; 36 37 38 /** 39 * Represents a thread waiting for a connection. 40 * This class implements throwaway objects. It is instantiated whenever 41 * a thread needs to wait. Instances are not re-used, except if the 42 * waiting thread experiences a spurious wakeup and continues to wait. 43 * <br/> 44 * All methods assume external synchronization on the condition 45 * passed to the constructor. 46 * Instances of this class do <i>not</i> synchronize access! 47 * 48 * @author <a href="mailto:rolandw at apache.org">Roland Weber</a> 49 * 50 * @deprecated Please use {@link java.net.URL#openConnection} instead. 51 * Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a> 52 * for further details. 53 */ 54 @Deprecated 55 public class WaitingThread { 56 57 /** The condition on which the thread is waiting. */ 58 private final Condition cond; 59 60 /** The route specific pool on which the thread is waiting. */ 61 //@@@ replace with generic pool interface 62 private final RouteSpecificPool pool; 63 64 /** The thread that is waiting for an entry. */ 65 private Thread waiter; 66 67 /** True if this was interrupted. */ 68 private boolean aborted; 69 70 71 /** 72 * Creates a new entry for a waiting thread. 73 * 74 * @param cond the condition for which to wait 75 * @param pool the pool on which the thread will be waiting, 76 * or <code>null</code> 77 */ WaitingThread(Condition cond, RouteSpecificPool pool)78 public WaitingThread(Condition cond, RouteSpecificPool pool) { 79 80 if (cond == null) { 81 throw new IllegalArgumentException("Condition must not be null."); 82 } 83 84 this.cond = cond; 85 this.pool = pool; 86 } 87 88 89 /** 90 * Obtains the condition. 91 * 92 * @return the condition on which to wait, never <code>null</code> 93 */ getCondition()94 public final Condition getCondition() { 95 // not synchronized 96 return this.cond; 97 } 98 99 100 /** 101 * Obtains the pool, if there is one. 102 * 103 * @return the pool on which a thread is or was waiting, 104 * or <code>null</code> 105 */ getPool()106 public final RouteSpecificPool getPool() { 107 // not synchronized 108 return this.pool; 109 } 110 111 112 /** 113 * Obtains the thread, if there is one. 114 * 115 * @return the thread which is waiting, or <code>null</code> 116 */ getThread()117 public final Thread getThread() { 118 // not synchronized 119 return this.waiter; 120 } 121 122 123 /** 124 * Blocks the calling thread. 125 * This method returns when the thread is notified or interrupted, 126 * if a timeout occurrs, or if there is a spurious wakeup. 127 * <br/> 128 * This method assumes external synchronization. 129 * 130 * @param deadline when to time out, or <code>null</code> for no timeout 131 * 132 * @return <code>true</code> if the condition was satisfied, 133 * <code>false</code> in case of a timeout. 134 * Typically, a call to {@link #wakeup} is used to indicate 135 * that the condition was satisfied. Since the condition is 136 * accessible outside, this cannot be guaranteed though. 137 * 138 * @throws InterruptedException if the waiting thread was interrupted 139 * 140 * @see #wakeup 141 */ await(Date deadline)142 public boolean await(Date deadline) 143 throws InterruptedException { 144 145 // This is only a sanity check. We cannot synchronize here, 146 // the lock would not be released on calling cond.await() below. 147 if (this.waiter != null) { 148 throw new IllegalStateException 149 ("A thread is already waiting on this object." + 150 "\ncaller: " + Thread.currentThread() + 151 "\nwaiter: " + this.waiter); 152 } 153 154 if (aborted) 155 throw new InterruptedException("Operation interrupted"); 156 157 this.waiter = Thread.currentThread(); 158 159 boolean success = false; 160 try { 161 if (deadline != null) { 162 success = this.cond.awaitUntil(deadline); 163 } else { 164 this.cond.await(); 165 success = true; 166 } 167 if (aborted) 168 throw new InterruptedException("Operation interrupted"); 169 } finally { 170 this.waiter = null; 171 } 172 return success; 173 174 } // await 175 176 177 /** 178 * Wakes up the waiting thread. 179 * <br/> 180 * This method assumes external synchronization. 181 */ wakeup()182 public void wakeup() { 183 184 // If external synchronization and pooling works properly, 185 // this cannot happen. Just a sanity check. 186 if (this.waiter == null) { 187 throw new IllegalStateException 188 ("Nobody waiting on this object."); 189 } 190 191 // One condition might be shared by several WaitingThread instances. 192 // It probably isn't, but just in case: wake all, not just one. 193 this.cond.signalAll(); 194 } 195 interrupt()196 public void interrupt() { 197 aborted = true; 198 this.cond.signalAll(); 199 } 200 201 202 } // class WaitingThread 203