From 2d028a0449b4e1e8b1a35ff68f531e5b6ca7c75f Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Thu, 10 Aug 2017 09:34:43 +0200 Subject: 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()) --- src/main.cc | 2 +- src/resolver.cc | 48 ++++++++++++++++++++++++++++++++++-------------- src/resolver.hh | 4 +++- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/main.cc b/src/main.cc index d03dd45..cd73833 100644 --- a/src/main.cc +++ b/src/main.cc @@ -172,7 +172,7 @@ int main(int argc, char** argv) { auto foreground = config->get("foreground", false); auto cwd = get_cwd(); std::unique_ptr looper(Looper::create()); - std::unique_ptr resolver(Resolver::create(looper.get())); + std::unique_ptr resolver(Resolver::create(looper.get(), true)); std::unique_ptr proxy( Proxy::create(config.get(), cwd, configfile, foreground ? "bogus" : 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(ptr); req->canceled = true; std::unique_lock lock(mutex_); @@ -196,12 +215,13 @@ protected: std::unique_ptr buf_; size_t fill_; bool quit_; + bool setup_; std::vector threads_; }; } // namespace // static -Resolver* Resolver::create(Looper* looper) { - return new ResolverImpl(looper); +Resolver* Resolver::create(Looper* looper, bool delay) { + return new ResolverImpl(looper, delay); } diff --git a/src/resolver.hh b/src/resolver.hh index 856f561..319f8b1 100644 --- a/src/resolver.hh +++ b/src/resolver.hh @@ -15,7 +15,9 @@ public: virtual ~Resolver() {} - static Resolver* create(Looper* looper); + static Resolver* create(Looper* looper, bool delay = false); + + virtual bool setup() = 0; virtual void* request(std::string const& host, uint16_t port, Callback const& callback) = 0; -- cgit v1.2.3-70-g09d2