mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-06 20:43:44 +02:00
Small thread safety fix in HttpClient.
This commit is contained in:
parent
4f0fcc582e
commit
f281886bfd
1 changed files with 27 additions and 9 deletions
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue