summaryrefslogtreecommitdiff
path: root/src/resolver.cc
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@yahoo.com>2017-08-10 09:34:43 +0200
committerJoel Klinghed <the_jk@yahoo.com>2017-08-10 09:34:43 +0200
commit2d028a0449b4e1e8b1a35ff68f531e5b6ca7c75f (patch)
treeb3b4df2ce4ae0317bcc9cf9ff4b3521739a76c76 /src/resolver.cc
parent2b062ae29bbc86008899c05e807fd9096ed9720d (diff)
Resolver didn't work when it was created before fork() and used after
The pipe that resolver sets up to communicate with the threads gets duplicated by the fork() leading to it all breaking down. So make it possible to create a Resolver without actually initializing it so we can do that *after* fork() (fork is called bu daemon())
Diffstat (limited to 'src/resolver.cc')
-rw-r--r--src/resolver.cc48
1 files changed, 34 insertions, 14 deletions
diff --git a/src/resolver.cc b/src/resolver.cc
index 2623089..68b4533 100644
--- a/src/resolver.cc
+++ b/src/resolver.cc
@@ -22,9 +22,32 @@ size_t const WORKERS = 4;
class ResolverImpl : public Resolver {
public:
- ResolverImpl(Looper* looper)
+ ResolverImpl(Looper* looper, bool delay)
: looper_(looper), request_(nullptr), buf_(new char[sizeof(Request*)]),
- fill_(0), quit_(false) {
+ fill_(0), quit_(false), setup_(false) {
+ if (!delay) {
+ if (!setup()) {
+ assert(false);
+ }
+ }
+ }
+
+ ~ResolverImpl() override {
+ quit_ = true;
+ if (setup_) {
+ cond_.notify_all();
+ for (auto& thread : threads_) {
+ thread.join();
+ }
+ }
+ }
+
+ bool setup() override {
+ if (setup_) {
+ assert(false);
+ return true;
+ }
+ setup_ = true;
while (threads_.size() < WORKERS) {
threads_.emplace_back(std::bind(&ResolverImpl::worker, this));
}
@@ -33,21 +56,16 @@ public:
Looper::EVENT_READ,
std::bind(&ResolverImpl::event, this,
std::placeholders::_1, std::placeholders::_2));
- } else {
- assert(false);
- }
- }
-
- ~ResolverImpl() override {
- quit_ = true;
- cond_.notify_all();
- for (auto& thread : threads_) {
- thread.join();
+ return true;
}
+ return false;
}
void* request(std::string const& host, uint16_t port,
Callback const& callback) override {
+ if (!setup_) {
+ setup();
+ }
auto req = new Request();
req->host = host;
req->port = port;
@@ -61,6 +79,7 @@ public:
}
void cancel(void* ptr) override {
+ assert(setup_);
auto req = reinterpret_cast<Request*>(ptr);
req->canceled = true;
std::unique_lock<std::mutex> lock(mutex_);
@@ -196,12 +215,13 @@ protected:
std::unique_ptr<char[]> buf_;
size_t fill_;
bool quit_;
+ bool setup_;
std::vector<std::thread> threads_;
};
} // namespace
// static
-Resolver* Resolver::create(Looper* looper) {
- return new ResolverImpl(looper);
+Resolver* Resolver::create(Looper* looper, bool delay) {
+ return new ResolverImpl(looper, delay);
}