Small thread safety fix in HttpClient.

This commit is contained in:
Adam Ierymenko 2014-08-16 13:32:33 -07:00
parent 4f0fcc582e
commit f281886bfd

View file

@ -149,6 +149,11 @@ public:
curlArgs[argPtr++] = const_cast <char *>(_url.c_str()); curlArgs[argPtr++] = const_cast <char *>(_url.c_str());
curlArgs[argPtr] = (char *)0; curlArgs[argPtr] = (char *)0;
if (_cancelled) {
delete this;
return;
}
int curlStdout[2]; int curlStdout[2];
int curlStderr[2]; int curlStderr[2];
::pipe(curlStdout); ::pipe(curlStdout);
@ -175,7 +180,8 @@ public:
unsigned long long timesOutAt = Utils::now() + ((unsigned long long)_timeout * 1000ULL); unsigned long long timesOutAt = Utils::now() + ((unsigned long long)_timeout * 1000ULL);
bool timedOut = false; bool timedOut = false;
bool tooLong = false; bool tooLong = false;
for(;;) {
while (!_cancelled) {
FD_ZERO(&readfds); FD_ZERO(&readfds);
FD_ZERO(&writefds); FD_ZERO(&writefds);
FD_ZERO(&errfds); FD_ZERO(&errfds);
@ -196,18 +202,18 @@ public:
} else if (n < 0) } else if (n < 0)
break; break;
if (_body.length() > CURL_MAX_MESSAGE_LENGTH) { if (_body.length() > CURL_MAX_MESSAGE_LENGTH) {
::kill(_pid,SIGKILL);
tooLong = true; tooLong = true;
break; break;
} }
} }
if (FD_ISSET(curlStderr[0],&readfds)) if (FD_ISSET(curlStderr[0],&readfds))
::read(curlStderr[0],buf,sizeof(buf)); ::read(curlStderr[0],buf,sizeof(buf));
if (FD_ISSET(curlStdout[0],&errfds)||FD_ISSET(curlStderr[0],&errfds)) if (FD_ISSET(curlStdout[0],&errfds)||FD_ISSET(curlStderr[0],&errfds))
break; break;
if (Utils::now() >= timesOutAt) { if (Utils::now() >= timesOutAt) {
::kill(_pid,SIGKILL);
timedOut = true; timedOut = true;
break; break;
} }
@ -231,8 +237,10 @@ public:
} }
} }
if (_pid > 0) if (_pid > 0) {
::kill(_pid,SIGKILL);
waitpid(_pid,&exitCode,0); waitpid(_pid,&exitCode,0);
}
_pid = 0; _pid = 0;
::close(curlStdout[0]); ::close(curlStdout[0]);
@ -491,17 +499,27 @@ HttpClient::~HttpClient()
Mutex::Lock _l(_requests_m); Mutex::Lock _l(_requests_m);
reqs = _requests; reqs = _requests;
} }
for(std::set<Request>::iterator r(reqs.begin());r!=reqs.end();++r) for(std::set<Request>::iterator r(reqs.begin());r!=reqs.end();++r)
this->cancel(*r); this->cancel(*r);
for(;;) {
_requests_m.lock();
if (_requests.empty()) {
_requests_m.unlock();
break;
} else {
_requests_m.unlock();
Thread::sleep(250);
}
}
} }
void HttpClient::cancel(HttpClient::Request req) void HttpClient::cancel(HttpClient::Request req)
{ {
{ Mutex::Lock _l(_requests_m);
Mutex::Lock _l(_requests_m); if (_requests.count(req) == 0)
if (_requests.count(req) == 0) return;
return;
}
((HttpClient_Private_Request *)req)->cancel(); ((HttpClient_Private_Request *)req)->cancel();
} }