Fixed race condition segmentation fault in HTTP proxy.
This commit is contained in:
parent
898cc961ad
commit
60cd55184c
1 changed files with 34 additions and 22 deletions
|
@ -400,23 +400,45 @@ namespace Connector_HTTP {
|
||||||
std::string orig_url = H.getUrl();
|
std::string orig_url = H.getUrl();
|
||||||
H.Clean();
|
H.Clean();
|
||||||
|
|
||||||
//check if a connection exists, and if not create one
|
ConnConn * myCConn = 0;
|
||||||
connMutex.lock();
|
//loop until a connection is available/created
|
||||||
if ( !connectorConnections.count(uid) || (!connectorConnections[uid]->conn->spool() && !connectorConnections[uid]->conn->connected())){
|
while (!myCConn){
|
||||||
if (connectorConnections.count(uid)){
|
//lock the connection mutex before trying anything
|
||||||
delete connectorConnections[uid];
|
connMutex.lock();
|
||||||
connectorConnections.erase(uid);
|
//check if a connection exists, and if not create one
|
||||||
}
|
if ( !connectorConnections.count(uid)){
|
||||||
connectorConnections[uid] = new ConnConn(new Socket::Connection(Util::getTmpFolder() + connector));
|
connectorConnections[uid] = new ConnConn(new Socket::Connection(Util::getTmpFolder() + connector));
|
||||||
connectorConnections[uid]->conn->setBlocking(false); //do not block on spool() with no data
|
connectorConnections[uid]->conn->setBlocking(false); //do not block on spool() with no data
|
||||||
#if DEBUG >= 4
|
#if DEBUG >= 4
|
||||||
std::cout << "Created new connection " << uid << std::endl;
|
std::cout << "Created new connection " << uid << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}else{
|
}else{
|
||||||
#if DEBUG >= 5
|
#if DEBUG >= 5
|
||||||
std::cout << "Re-using connection " << uid << std::endl;
|
std::cout << "Re-using connection " << uid << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//attempt to lock the mutex for this connection
|
||||||
|
if (connectorConnections[uid]->inUse.try_lock()){
|
||||||
|
myCConn = connectorConnections[uid];
|
||||||
|
//if the connection is dead, delete it and re-loop
|
||||||
|
if (!myCConn->conn->spool() && !myCConn->conn->connected()){
|
||||||
|
connectorConnections.erase(uid);
|
||||||
|
myCConn->inUse.unlock();
|
||||||
|
delete myCConn;
|
||||||
|
myCConn = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//unlock the connection mutex before sleeping
|
||||||
|
connMutex.unlock();
|
||||||
|
//no connection yet? wait for 0.1 second and try again
|
||||||
|
if ( !myCConn){
|
||||||
|
Util::sleep(100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//we now have a locked, working connection
|
||||||
|
|
||||||
{//start a new timeout thread, if neccesary
|
{//start a new timeout thread, if neccesary
|
||||||
tthread::lock_guard<tthread::mutex> guard(timeoutStartMutex);
|
tthread::lock_guard<tthread::mutex> guard(timeoutStartMutex);
|
||||||
if (timeoutMutex.try_lock()){
|
if (timeoutMutex.try_lock()){
|
||||||
|
@ -431,16 +453,6 @@ namespace Connector_HTTP {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//lock the mutex for this connection, and handle the request
|
|
||||||
ConnConn * myCConn = connectorConnections[uid];
|
|
||||||
myCConn->inUse.lock();
|
|
||||||
connMutex.unlock();
|
|
||||||
//if the server connection is dead, handle as timeout.
|
|
||||||
if ( !myCConn->conn->connected()){
|
|
||||||
myCConn->conn->close();
|
|
||||||
myCConn->inUse.unlock();
|
|
||||||
return proxyHandleTimeout(H, conn);
|
|
||||||
}
|
|
||||||
//forward the original request
|
//forward the original request
|
||||||
myCConn->conn->SendNow(request);
|
myCConn->conn->SendNow(request);
|
||||||
myCConn->lastUse = 0;
|
myCConn->lastUse = 0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue