From 92ad50a8e73b71e1fa07e56450ecf2cc69a2536c Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Wed, 27 Feb 2019 16:27:42 -0800 Subject: [PATCH] Destroy abandoned websocket ops on shutdown fix #1358 --- CHANGELOG.md | 1 + doc/qbk/release_notes.qbk | 2 ++ include/boost/beast/core/impl/saved_handler.ipp | 10 ++++++++++ include/boost/beast/core/saved_handler.hpp | 10 ++++++++++ include/boost/beast/websocket/detail/service.hpp | 7 +++++++ include/boost/beast/websocket/impl/stream_impl.hpp | 12 ++++++++++++ 6 files changed, 42 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8226948..e6bcaea7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ Version 223: * Add test::stream::service * Add websocket service * Pausation abandoning test +* Destroy abandoned websocket ops on shutdown -------------------------------------------------------------------------------- diff --git a/doc/qbk/release_notes.qbk b/doc/qbk/release_notes.qbk index b9bc09e9..ca3f1f65 100644 --- a/doc/qbk/release_notes.qbk +++ b/doc/qbk/release_notes.qbk @@ -335,6 +335,8 @@ * ([issue 1306]) `test::stream` has fewer dependencies +* ([issue 1358]) Destroy abandoned websocket ops on shutdown + * ([issue 1365]) Handler wrappers decay parameters sooner * ([issue 1408]) `session_alloc` diff --git a/include/boost/beast/core/impl/saved_handler.ipp b/include/boost/beast/core/impl/saved_handler.ipp index 779339c6..30ecbc8e 100644 --- a/include/boost/beast/core/impl/saved_handler.ipp +++ b/include/boost/beast/core/impl/saved_handler.ipp @@ -39,6 +39,16 @@ operator=(saved_handler&& other) noexcept return *this; } +bool +saved_handler:: +reset() noexcept +{ + if(! p_) + return false; + boost::exchange(p_, nullptr)->destroy(); + return true; +} + void saved_handler:: invoke() diff --git a/include/boost/beast/core/saved_handler.hpp b/include/boost/beast/core/saved_handler.hpp index 08aafdbc..a4599d42 100644 --- a/include/boost/beast/core/saved_handler.hpp +++ b/include/boost/beast/core/saved_handler.hpp @@ -90,6 +90,16 @@ public: void emplace(Handler&& handler); + /** Discard the saved handler, if one exists. + + If `*this` contains an object, it is destroyed. + + @returns `true` if an object was destroyed. + */ + BOOST_BEAST_DECL + bool + reset() noexcept; + /** Unconditionally invoke the stored completion handler. Requires `this->has_value() == true`. Any dynamic memory diff --git a/include/boost/beast/websocket/detail/service.hpp b/include/boost/beast/websocket/detail/service.hpp index 62b1dcb8..b34e4215 100644 --- a/include/boost/beast/websocket/detail/service.hpp +++ b/include/boost/beast/websocket/detail/service.hpp @@ -55,6 +55,10 @@ public: svc_.v_[index_] = &other; svc_.v_.pop_back(); } + + virtual + void + shutdown() = 0; }; private: @@ -72,6 +76,9 @@ private: for(auto p : v_) v.emplace_back(p->weak_from_this()); } + for(auto wp : v) + if(auto sp = wp.lock()) + sp->shutdown(); } public: diff --git a/include/boost/beast/websocket/impl/stream_impl.hpp b/include/boost/beast/websocket/impl/stream_impl.hpp index 82f526a0..8f6ef050 100644 --- a/include/boost/beast/websocket/impl/stream_impl.hpp +++ b/include/boost/beast/websocket/impl/stream_impl.hpp @@ -138,6 +138,18 @@ struct stream::impl_type timeout_opt.keep_alive_pings = false; } + void + shutdown() override + { + op_rd.reset(); + op_wr.reset(); + op_ping.reset(); + op_idle_ping.reset(); + op_close.reset(); + op_r_rd.reset(); + op_r_close.reset(); + } + void open(role_type role_) {