dns lookup: fix race condition accessing _errMsg

This commit is contained in:
Benjamin Sergeant 2019-04-29 19:29:27 -07:00
parent 9dca893ce7
commit 6d310d417a
2 changed files with 41 additions and 16 deletions

View File

@ -17,7 +17,6 @@ namespace ix
std::atomic<uint64_t> DNSLookup::_nextId(0); std::atomic<uint64_t> DNSLookup::_nextId(0);
std::set<uint64_t> DNSLookup::_activeJobs; std::set<uint64_t> DNSLookup::_activeJobs;
std::mutex DNSLookup::_activeJobsMutex; std::mutex DNSLookup::_activeJobsMutex;
std::mutex DNSLookup::_resMutex;
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),
@ -137,13 +136,8 @@ namespace ix
return nullptr; return nullptr;
} }
if (!_errMsg.empty()) errMsg = getErrMsg();
{ return getRes();
errMsg = _errMsg;
}
std::unique_lock<std::mutex> rlock(_resMutex);
return _res;
} }
void DNSLookup::run(uint64_t id, std::string hostname, int port) // thread runner void DNSLookup::run(uint64_t id, std::string hostname, int port) // thread runner
@ -155,7 +149,7 @@ namespace ix
struct addrinfo* res = getAddrInfo(hostname, port, errMsg); struct addrinfo* res = getAddrInfo(hostname, port, errMsg);
// if this isn't an active job, and the control thread is gone // 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 // there is nothing to do, and we don't want to touch the defunct
// object data structure such as _errMsg or _condition // object data structure such as _errMsg or _condition
std::unique_lock<std::mutex> lock(_activeJobsMutex); std::unique_lock<std::mutex> lock(_activeJobsMutex);
if (_activeJobs.count(id) == 0) if (_activeJobs.count(id) == 0)
@ -164,12 +158,34 @@ namespace ix
} }
// Copy result into the member variables // Copy result into the member variables
{ setRes(res);
std::unique_lock<std::mutex> rlock(_resMutex); setErrMsg(errMsg);
_res = res;
}
_errMsg = errMsg;
_condition.notify_one(); _condition.notify_one();
_done = true; _done = true;
} }
void DNSLookup::setErrMsg(const std::string& errMsg)
{
std::unique_lock<std::mutex> lock(_errMsgMutex);
_errMsg = errMsg;
}
const std::string& DNSLookup::getErrMsg()
{
std::unique_lock<std::mutex> lock(_errMsgMutex);
return _errMsg;
}
void DNSLookup::setRes(struct addrinfo* addr)
{
std::unique_lock<std::mutex> lock(_resMutex);
_res = addr;
}
struct addrinfo* DNSLookup::getRes()
{
std::unique_lock<std::mutex> lock(_resMutex);
return _res;
}
} }

View File

@ -45,12 +45,21 @@ namespace ix
void run(uint64_t id, std::string hostname, int port); // thread runner void run(uint64_t id, std::string hostname, int port); // thread runner
void setErrMsg(const std::string& errMsg);
const std::string& getErrMsg();
void setRes(struct addrinfo* addr);
struct addrinfo* getRes();
std::string _hostname; std::string _hostname;
int _port; int _port;
int64_t _wait; int64_t _wait;
std::string _errMsg;
struct addrinfo* _res; struct addrinfo* _res;
static std::mutex _resMutex; std::mutex _resMutex;
std::string _errMsg;
std::mutex _errMsgMutex;
std::atomic<bool> _done; std::atomic<bool> _done;
std::thread _thread; std::thread _thread;