diff options
| author | Joel Klinghed <the_jk@yahoo.com> | 2017-08-10 09:34:43 +0200 |
|---|---|---|
| committer | Joel Klinghed <the_jk@yahoo.com> | 2017-08-10 09:34:43 +0200 |
| commit | 2d028a0449b4e1e8b1a35ff68f531e5b6ca7c75f (patch) | |
| tree | b3b4df2ce4ae0317bcc9cf9ff4b3521739a76c76 /src/resolver.cc | |
| parent | 2b062ae29bbc86008899c05e807fd9096ed9720d (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.cc | 48 |
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); } |
