diff --git a/include/ircd/server/server.h b/include/ircd/server/server.h index e1a2e5c83..ca85c7c17 100644 --- a/include/ircd/server/server.h +++ b/include/ircd/server/server.h @@ -51,6 +51,8 @@ namespace ircd::server struct ircd::server::init { void interrupt(); + void close(); + void wait(); init(); ~init() noexcept; diff --git a/ircd/ircd.cc b/ircd/ircd.cc index fe9dae6f7..828a3a920 100644 --- a/ircd/ircd.cc +++ b/ircd/ircd.cc @@ -210,6 +210,7 @@ try { _server_.interrupt(); _client_.interrupt(); + _server_.close(); }}; // When the call to wait() below completes, IRCd exits from the RUN state diff --git a/ircd/server.cc b/ircd/server.cc index c0695afac..3ce51dd65 100644 --- a/ircd/server.cc +++ b/ircd/server.cc @@ -168,14 +168,6 @@ ircd::server::close_all() for(auto &peer : peers) peer.second->close(opts); - - log.debug("Waiting for %zu tags on %zu links on %zu peers to close...", - tag_count(), - link_count(), - peer_count()); - - while(link_count()) - dock.wait(); } void @@ -201,10 +193,33 @@ ircd::server::init::init() ircd::server::init::~init() noexcept +{ + close_all(); + wait(); + peers.clear(); +} + +void +ircd::server::init::wait() +{ + while(link_count()) + { + if(dock.wait_for(seconds(2)) == ctx::cv_status::no_timeout) + continue; + + log.warning("Waiting for %zu tags on %zu links on %zu peers to close...", + tag_count(), + link_count(), + peer_count()); + + } +} + +void +ircd::server::init::close() { ready = false; close_all(); - peers.clear(); } void @@ -525,6 +540,7 @@ ircd::server::peer::link_add(const size_t &num) if(e) std::rethrow_exception(e->eptr); + assert(ready); links.emplace_back(*this); auto &link{links.back()}; @@ -793,6 +809,10 @@ try } static_cast(this->remote) = ipport; + + if(!ready) + return; + for(auto &link : links) link.open(this->remote); } @@ -1066,6 +1086,8 @@ ircd::server::link::cancel_uncommitted(std::exception_ptr eptr) bool ircd::server::link::open(const net::open_opts &open_opts) { + assert(server::ready); + if(op_init) return false;