async dns lookup fix

This commit is contained in:
Benjamin Sergeant 2018-12-14 17:49:42 -08:00
parent cbadecab33
commit bd04b28b9e
2 changed files with 37 additions and 5 deletions

View File

@ -18,19 +18,26 @@ namespace ix
const int64_t DNSLookup::kDefaultTimeout = 60 * 1000; // ms
const int64_t DNSLookup::kDefaultWait = 10; // ms
std::atomic<uint64_t> DNSLookup::_nextId(0);
std::set<uint64_t> DNSLookup::_activeJobs;
std::mutex DNSLookup::_activeJobsMutex;
DNSLookup::DNSLookup(const std::string& hostname, int port, int wait) :
_hostname(hostname),
_port(port),
_res(nullptr),
_done(false),
_wait(wait)
_wait(wait),
_id(_nextId++)
{
}
DNSLookup::~DNSLookup()
{
;
// Remove this job from the active jobs list
std::unique_lock<std::mutex> lock(_activeJobsMutex);
_activeJobs.erase(_id);
}
struct addrinfo* DNSLookup::getAddrInfo(const std::string& hostname,
@ -92,6 +99,12 @@ namespace ix
// if you need a second lookup.
}
// Record job in the active Job set
{
std::unique_lock<std::mutex> lock(_activeJobsMutex);
_activeJobs.insert(_id);
}
//
// Good resource on thread forced termination
// https://www.bo-yang.net/2017/11/19/cpp-kill-detached-thread
@ -100,7 +113,7 @@ namespace ix
_thread.detach();
int64_t timeout = kDefaultTimeout;
std::unique_lock<std::mutex> lock(_mutex);
std::unique_lock<std::mutex> lock(_conditionVariableMutex);
while (!_done)
{
@ -140,7 +153,20 @@ namespace ix
void DNSLookup::run()
{
_res = getAddrInfo(_hostname, _port, _errMsg);
uint64_t id = _id;
std::string errMsg;
_res = getAddrInfo(_hostname, _port, errMsg);
// if this isn't an active job, and the control thread is gone
// there is not thing to do, and we don't want to touch the defunct
// object data structure such as _errMsg or _condition
std::unique_lock<std::mutex> lock(_activeJobsMutex);
if (_activeJobs.count(id) == 0)
{
return;
}
_errMsg = errMsg;
_condition.notify_one();
_done = true;
}

View File

@ -16,6 +16,7 @@
#include <thread>
#include <atomic>
#include <condition_variable>
#include <set>
struct addrinfo;
@ -53,7 +54,12 @@ namespace ix
std::atomic<bool> _done;
std::thread _thread;
std::condition_variable _condition;
std::mutex _mutex;
std::mutex _conditionVariableMutex;
std::atomic<uint64_t> _id;
static std::atomic<uint64_t> _nextId;
static std::set<uint64_t> _activeJobs;
static std::mutex _activeJobsMutex;
const static int64_t kDefaultTimeout;
const static int64_t kDefaultWait;