Fixed race condition segmentation fault in HTTP proxy.

This commit is contained in:
Thulinma 2013-10-02 15:06:35 +02:00
parent 898cc961ad
commit 60cd55184c

View file

@ -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;