mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/WaitingThread.java

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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  */
    27 package ch.boye.httpclientandroidlib.impl.conn.tsccm;
    30 import java.util.Date;
    31 import java.util.concurrent.locks.Condition;
    33 import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
    35 /**
    36  * Represents a thread waiting for a connection.
    37  * This class implements throwaway objects. It is instantiated whenever
    38  * a thread needs to wait. Instances are not re-used, except if the
    39  * waiting thread experiences a spurious wakeup and continues to wait.
    40  * <br/>
    41  * All methods assume external synchronization on the condition
    42  * passed to the constructor.
    43  * Instances of this class do <i>not</i> synchronize access!
    44  *
    45  *
    46  * @since 4.0
    47  */
    48 @NotThreadSafe
    49 public class WaitingThread {
    51     /** The condition on which the thread is waiting. */
    52     private final Condition cond;
    54     /** The route specific pool on which the thread is waiting. */
    55     //@@@ replace with generic pool interface
    56     private final RouteSpecificPool pool;
    58     /** The thread that is waiting for an entry. */
    59     private Thread waiter;
    61     /** True if this was interrupted. */
    62     private boolean aborted;
    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) {
    74         if (cond == null) {
    75             throw new IllegalArgumentException("Condition must not be null.");
    76         }
    78         this.cond = cond;
    79         this.pool = pool;
    80     }
    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     }
    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     }
   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     }
   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 {
   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         }
   148         if (aborted)
   149             throw new InterruptedException("Operation interrupted");
   151         this.waiter = Thread.currentThread();
   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;
   168     } // await
   171     /**
   172      * Wakes up the waiting thread.
   173      * <br/>
   174      * This method assumes external synchronization.
   175      */
   176     public void wakeup() {
   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         }
   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     }
   190     public void interrupt() {
   191         aborted = true;
   192         this.cond.signalAll();
   193     }
   196 } // class WaitingThread

mercurial