View Javadoc

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