List of usage examples for org.apache.http.impl.conn.tsccm WaitingThread await
public boolean await(final Date deadline) throws InterruptedException
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/* w w w . j a va 2 s. c o m*/ * @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; }