Example #1
0
TcpTransport& ConnectionPool::borrowObject(const InetSocketAddress& key) {
    if (closed) {
        throw new HotRodClientException("Pool is closed");
    }
    if (!idle.count(key) || !busy.count(key)) {
        throw new HotRodClientException("Pool is closed");
    }
    TransportQueuePtr idleQ = idle[key];
    TransportQueuePtr busyQ = busy[key];

    // See if an object is readily available
    TcpTransport* obj;
    bool ok = idleQ->poll(obj);

    for (;;) {
        if (ok) {
            // Check if the object is still valid, if not destroy it
            if (configuration.isTestOnBorrow() && !factory->validateObject(key, *obj)) {
                factory->destroyObject(key, *obj);
                ok = false;
            }
            // We have a valid object
            if (ok) {
                busyQ->push(obj);
                break;
            }
        }
        // See if we can create a new one
        if (busyQ->size() < configuration.getMaxActive()) {
            obj = &factory->makeObject(key);
        } else {
            // Wait for an object to become idle
            obj = idleQ->pop();
        }
        ok = true;
    }
    factory->activateObject(key, *obj);
    return *obj;
}
Example #2
0
TcpTransport& ConnectionPool::borrowObject(const InetSocketAddress& key) {
	sys::ScopedLock<sys::Mutex> l(lock);

    if (closed) {
        throw HotRodClientException("Pool is closed");
    }
    if (!idle.count(key) || !busy.count(key)) {
        throw HotRodClientException("Pool has no idle or no busy transports.");
    }
    TransportQueuePtr idleQ = idle[key];
    TransportQueuePtr busyQ = busy[key];

    // See if an object is readily available
    TcpTransport* obj = NULL;
    bool ok = idleQ->poll(obj);
    if (ok) {
        totalIdle--;
    }

    for (;;) {
        if (ok) {
            // Check if the object is still valid, if not destroy it
            if (configuration.isTestOnBorrow() && !factory->validateObject(key, *obj)) {
                factory->destroyObject(key, *obj);
                ok = false;
            }
            // We have a valid object
            if (ok) {
                busyQ->push(obj);
                totalActive++;
                break;
            }
        }
        // See if we can create a new one
        if (idleQ->size() == 0 && //the idle queue is empty
                (configuration.getMaxActive() < 0 || busyQ->size() < (size_t) configuration.getMaxActive()) && //max active not reached!
				!hasReachedMaxTotal()) {
            obj = &factory->makeObject(key);
		} else if (hasReachedMaxTotal()) {
			//max total reached. try to destroy a existing idle connection. if not possible, wait until some other connection is available.
			if (tryRemoveIdle()) { //removal successful.
				obj = &factory->makeObject(key);
			} else {
				allocationQueue.push(key);
				{
					sys::ScopedUnlock<sys::Mutex> u(lock);
					obj = idleQ->pop();
				}
				totalIdle--;
			}
		} else {
			// Wait for an object to become idle
			{
				sys::ScopedUnlock<sys::Mutex> u(lock);
				obj = idleQ->pop();
			}
			totalIdle--;
		}
		ok = true;
    }
    factory->activateObject(key, *obj);
    return *obj;
}