make IXDNSLookup more robust

This commit is contained in:
Benjamin Sergeant 2019-06-26 19:12:48 -07:00
parent 3750781bce
commit 5b73edec8c
2 changed files with 13 additions and 20 deletions

View File

@ -9,10 +9,11 @@
#include <string.h> #include <string.h>
#include <chrono> #include <chrono>
#include <thread>
namespace ix namespace ix
{ {
const int64_t DNSLookup::kDefaultWait = 10; // ms const int64_t DNSLookup::kDefaultWait = 1; // ms
DNSLookup::DNSLookup(const std::string& hostname, int port, int64_t wait) : DNSLookup::DNSLookup(const std::string& hostname, int port, int64_t wait) :
_hostname(hostname), _hostname(hostname),
@ -92,20 +93,19 @@ namespace ix
int port = _port; int port = _port;
std::string hostname(_hostname); std::string hostname(_hostname);
_thread = std::thread(&DNSLookup::run, this, self, hostname, port);
_thread.detach();
std::unique_lock<std::mutex> lock(_conditionVariableMutex); // We make the background thread doing the work a shared pointer
// instead of a member variable, because it can keep running when
// this object goes out of scope, in case of cancellation
auto t = std::make_shared<std::thread>(&DNSLookup::run, this, self, hostname, port);
t->detach();
while (!_done) while (!_done)
{ {
// Wait for 10 milliseconds on the condition variable, to see // Wait for 1 milliseconds, to see if the bg thread has terminated.
// if the bg thread has terminated. // We do not use a condition variable to wait, as destroying this one
if (_condition.wait_for(lock, std::chrono::milliseconds(_wait)) == std::cv_status::no_timeout) // if the bg thread is alive can cause undefined behavior.
{ std::this_thread::sleep_for(std::chrono::milliseconds(_wait));
// Background thread has terminated, so we can break of this loop
break;
}
// Were we cancelled ? // Were we cancelled ?
if (isCancellationRequested && isCancellationRequested()) if (isCancellationRequested && isCancellationRequested())
@ -140,7 +140,6 @@ namespace ix
setRes(res); setRes(res);
setErrMsg(errMsg); setErrMsg(errMsg);
_condition.notify_one();
_done = true; _done = true;
} }
} }

View File

@ -12,10 +12,9 @@
#include "IXCancellationRequest.h" #include "IXCancellationRequest.h"
#include <atomic> #include <atomic>
#include <condition_variable> #include <mutex>
#include <set> #include <set>
#include <string> #include <string>
#include <thread>
#include <memory> #include <memory>
struct addrinfo; struct addrinfo;
@ -52,8 +51,8 @@ namespace ix
std::string _hostname; std::string _hostname;
int _port; int _port;
int64_t _wait; int64_t _wait;
const static int64_t kDefaultWait;
struct addrinfo* _res; struct addrinfo* _res;
std::mutex _resMutex; std::mutex _resMutex;
@ -62,10 +61,5 @@ namespace ix
std::mutex _errMsgMutex; std::mutex _errMsgMutex;
std::atomic<bool> _done; std::atomic<bool> _done;
std::thread _thread;
std::condition_variable _condition;
std::mutex _conditionVariableMutex;
const static int64_t kDefaultWait;
}; };
} // namespace ix } // namespace ix