Example usage for org.apache.http.impl.conn.tsccm WaitingThreadAborter setWaitingThread

List of usage examples for org.apache.http.impl.conn.tsccm WaitingThreadAborter setWaitingThread

Introduction

In this page you can find the example usage for org.apache.http.impl.conn.tsccm WaitingThreadAborter setWaitingThread.

Prototype

public void setWaitingThread(final WaitingThread waitingThread) 

Source Link

Document

Sets the waiting thread.

Usage

From source file:org.apache.http.impl.conn.tsccm.ConnPoolByRoute.java

/**
 * Obtains a pool entry with a connection within the given timeout.
 * If a {@link WaitingThread} is used to block, {@link WaitingThreadAborter#setWaitingThread(WaitingThread)}
 * must be called before blocking, to allow the thread to be interrupted.
 *
 * @param route     the route for which to get the connection
 * @param timeout   the timeout, 0 or negative for no timeout
 * @param tunit     the unit for the <code>timeout</code>,
 *                  may be <code>null</code> only if there is no timeout
 * @param aborter   an object which can abort a {@link WaitingThread}.
 *
 * @return  pool entry holding a connection for the route
 *
 * @throws ConnectionPoolTimeoutException
 *         if the timeout expired/*from   w w w. j ava  2s.c  om*/
 * @throws InterruptedException
 *         if the calling thread was interrupted
 */
protected BasicPoolEntry getEntryBlocking(final HttpRoute route, final Object state, final long timeout,
        final TimeUnit tunit, final WaitingThreadAborter aborter)
        throws ConnectionPoolTimeoutException, InterruptedException {

    Date deadline = null;
    if (timeout > 0) {
        deadline = new Date(System.currentTimeMillis() + tunit.toMillis(timeout));
    }

    BasicPoolEntry entry = null;
    poolLock.lock();
    try {

        RouteSpecificPool rospl = getRoutePool(route, true);
        WaitingThread waitingThread = null;

        while (entry == null) {
            Asserts.check(!shutdown, "Connection pool shut down");

            if (log.isDebugEnabled()) {
                log.debug("[" + route + "] total kept alive: " + freeConnections.size() + ", total issued: "
                        + leasedConnections.size() + ", total allocated: " + numConnections + " out of "
                        + maxTotalConnections);
            }

            // the cases to check for:
            // - have a free connection for that route
            // - allowed to create a free connection for that route
            // - can delete and replace a free connection for another route
            // - need to wait for one of the things above to come true

            entry = getFreeEntry(rospl, state);
            if (entry != null) {
                break;
            }

            final boolean hasCapacity = rospl.getCapacity() > 0;

            if (log.isDebugEnabled()) {
                log.debug("Available capacity: " + rospl.getCapacity() + " out of " + rospl.getMaxEntries()
                        + " [" + route + "][" + state + "]");
            }

            if (hasCapacity && numConnections < maxTotalConnections) {

                entry = createEntry(rospl, operator);

            } else if (hasCapacity && !freeConnections.isEmpty()) {

                deleteLeastUsedEntry();
                // if least used entry's route was the same as rospl,
                // rospl is now out of date : we preemptively refresh
                rospl = getRoutePool(route, true);
                entry = createEntry(rospl, operator);

            } else {

                if (log.isDebugEnabled()) {
                    log.debug("Need to wait for connection" + " [" + route + "][" + state + "]");
                }

                if (waitingThread == null) {
                    waitingThread = newWaitingThread(poolLock.newCondition(), rospl);
                    aborter.setWaitingThread(waitingThread);
                }

                boolean success = false;
                try {
                    rospl.queueThread(waitingThread);
                    waitingThreads.add(waitingThread);
                    success = waitingThread.await(deadline);

                } finally {
                    // In case of 'success', we were woken up by the
                    // connection pool and should now have a connection
                    // waiting for us, or else we're shutting down.
                    // Just continue in the loop, both cases are checked.
                    rospl.removeThread(waitingThread);
                    waitingThreads.remove(waitingThread);
                }

                // check for spurious wakeup vs. timeout
                if (!success && (deadline != null) && (deadline.getTime() <= System.currentTimeMillis())) {
                    throw new ConnectionPoolTimeoutException("Timeout waiting for connection from pool");
                }
            }
        } // while no entry

    } finally {
        poolLock.unlock();
    }
    return entry;
}