Unverified Commit 52697cba authored by Dominik Charousset's avatar Dominik Charousset Committed by GitHub

Merge pull request #954

Avoid repeated calls to stream finalizers
parents fddc1747 dfd900c8
...@@ -47,10 +47,14 @@ public: ...@@ -47,10 +47,14 @@ public:
/// outbound paths exist. /// outbound paths exist.
static constexpr int is_continuous_flag = 0x0001; static constexpr int is_continuous_flag = 0x0001;
/// Denotes whether the stream is about to stop, only sending already /// Denotes whether the stream is about to stop, only sending buffered
/// buffered elements. /// elements.
static constexpr int is_shutting_down_flag = 0x0002; static constexpr int is_shutting_down_flag = 0x0002;
/// Denotes whether the manager has stopped. Calling member functions such as
/// stop() or abort() on it no longer has any effect.
static constexpr int is_stopped_flag = 0x0004;
// -- member types ----------------------------------------------------------- // -- member types -----------------------------------------------------------
using inbound_paths_list = std::vector<inbound_path*>; using inbound_paths_list = std::vector<inbound_path*>;
...@@ -143,22 +147,22 @@ public: ...@@ -143,22 +147,22 @@ public:
// -- properties ------------------------------------------------------------- // -- properties -------------------------------------------------------------
/// Returns whether this stream is shutting down. /// Returns whether this stream is neither shutting down nor has stopped.
bool shutting_down() const noexcept { bool running() const noexcept {
return getf(is_shutting_down_flag); return getf(is_shutting_down_flag | is_stopped_flag) == 0;
} }
/// Returns whether this stream remains open even if no in- or outbound paths /// Returns whether this stream remains open even if no in- or outbound paths
/// exist. The default is `false`. Does not keep a source alive past the /// exist. The default is `false`. Does not keep a source alive past the
/// point where its driver returns `done() == true`. /// point where its driver returns `done() == true`.
inline bool continuous() const noexcept { bool continuous() const noexcept {
return getf(is_continuous_flag); return getf(is_continuous_flag);
} }
/// Sets whether this stream remains open even if no in- or outbound paths /// Sets whether this stream remains open even if no in- or outbound paths
/// exist. /// exist.
inline void continuous(bool x) noexcept { void continuous(bool x) noexcept {
if (!shutting_down()) { if (running()) {
if (x) if (x)
setf(is_continuous_flag); setf(is_continuous_flag);
else else
...@@ -167,7 +171,7 @@ public: ...@@ -167,7 +171,7 @@ public:
} }
/// Returns the list of inbound paths. /// Returns the list of inbound paths.
inline const inbound_paths_list& inbound_paths() const noexcept{ const inbound_paths_list& inbound_paths() const noexcept {
return inbound_paths_; return inbound_paths_;
} }
...@@ -179,7 +183,7 @@ public: ...@@ -179,7 +183,7 @@ public:
bool inbound_paths_idle() const noexcept; bool inbound_paths_idle() const noexcept;
/// Returns the parent actor. /// Returns the parent actor.
inline scheduled_actor* self() { scheduled_actor* self() {
return self_; return self_;
} }
...@@ -265,7 +269,7 @@ public: ...@@ -265,7 +269,7 @@ public:
/// Adds the current sender as an inbound path. /// Adds the current sender as an inbound path.
/// @pre Current message is an `open_stream_msg`. /// @pre Current message is an `open_stream_msg`.
stream_slot add_unchecked_inbound_path_impl(rtti_pair rtti); stream_slot add_unchecked_inbound_path_impl(rtti_pair rtti);
protected: protected:
// -- modifiers for self ----------------------------------------------------- // -- modifiers for self -----------------------------------------------------
...@@ -322,9 +326,9 @@ private: ...@@ -322,9 +326,9 @@ private:
flags_ = x & ~flag; flags_ = x & ~flag;
} }
bool getf(int flag) const noexcept { bool getf(int flag) const noexcept {
return (flags_ & flag) != 0; return (flags_ & flag) != 0;
} }
}; };
/// A reference counting pointer to a `stream_manager`. /// A reference counting pointer to a `stream_manager`.
......
...@@ -305,6 +305,7 @@ struct downstream_msg_visitor { ...@@ -305,6 +305,7 @@ struct downstream_msg_visitor {
template <class T> template <class T>
intrusive::task_result operator()(T& x) { intrusive::task_result operator()(T& x) {
CAF_LOG_TRACE(CAF_ARG(x));
auto& inptr = q_ref.policy().handler; auto& inptr = q_ref.policy().handler;
if (inptr == nullptr) if (inptr == nullptr)
return intrusive::task_result::stop; return intrusive::task_result::stop;
...@@ -323,6 +324,7 @@ struct downstream_msg_visitor { ...@@ -323,6 +324,7 @@ struct downstream_msg_visitor {
qs_ref.erase_later(dm.slots.receiver); qs_ref.erase_later(dm.slots.receiver);
selfptr->erase_stream_manager(dm.slots.receiver); selfptr->erase_stream_manager(dm.slots.receiver);
if (mgr->done()) { if (mgr->done()) {
CAF_LOG_DEBUG("path is done receiving and closes its manager");
selfptr->erase_stream_manager(mgr); selfptr->erase_stream_manager(mgr);
mgr->stop(); mgr->stop();
} }
......
...@@ -37,10 +37,7 @@ ...@@ -37,10 +37,7 @@
namespace caf { namespace caf {
stream_manager::stream_manager(scheduled_actor* selfptr, stream_priority prio) stream_manager::stream_manager(scheduled_actor* selfptr, stream_priority prio)
: self_(selfptr), : self_(selfptr), pending_handshakes_(0), priority_(prio), flags_(0) {
pending_handshakes_(0),
priority_(prio),
flags_(0) {
// nop // nop
} }
...@@ -116,15 +113,21 @@ void stream_manager::handle(stream_slots slots, upstream_msg::ack_batch& x) { ...@@ -116,15 +113,21 @@ void stream_manager::handle(stream_slots slots, upstream_msg::ack_batch& x) {
} }
void stream_manager::handle(stream_slots slots, upstream_msg::drop&) { void stream_manager::handle(stream_slots slots, upstream_msg::drop&) {
CAF_LOG_TRACE(CAF_ARG(slots));
out().close(slots.receiver); out().close(slots.receiver);
} }
void stream_manager::handle(stream_slots slots, upstream_msg::forced_drop& x) { void stream_manager::handle(stream_slots slots, upstream_msg::forced_drop& x) {
CAF_LOG_TRACE(CAF_ARG(slots) << CAF_ARG(x));
if (out().remove_path(slots.receiver, x.reason, true)) if (out().remove_path(slots.receiver, x.reason, true))
stop(std::move(x.reason)); stop(std::move(x.reason));
} }
void stream_manager::stop(error reason) { void stream_manager::stop(error reason) {
CAF_LOG_TRACE(CAF_ARG(reason));
if (getf(is_stopped_flag))
return;
flags_ = is_stopped_flag;
if (reason) if (reason)
out().abort(reason); out().abort(reason);
else else
...@@ -135,12 +138,12 @@ void stream_manager::stop(error reason) { ...@@ -135,12 +138,12 @@ void stream_manager::stop(error reason) {
void stream_manager::shutdown() { void stream_manager::shutdown() {
CAF_LOG_TRACE(""); CAF_LOG_TRACE("");
// Mark as shutting down and reset other flags. if (!running())
if (shutting_down())
return; return;
flags_ = is_shutting_down_flag; flags_ = is_shutting_down_flag;
CAF_LOG_DEBUG("emit shutdown messages on" << inbound_paths_.size() CAF_LOG_DEBUG("emit shutdown messages on"
<< "inbound paths;" << CAF_ARG2("out.clean", out().clean()) << inbound_paths_.size() << "inbound paths;"
<< CAF_ARG2("out.clean", out().clean())
<< CAF_ARG2("out.paths", out().num_paths())); << CAF_ARG2("out.paths", out().num_paths()));
for (auto ipath : inbound_paths_) for (auto ipath : inbound_paths_)
ipath->emit_regular_shutdown(self_); ipath->emit_regular_shutdown(self_);
...@@ -233,15 +236,12 @@ void stream_manager::remove_input_path(stream_slot slot, error reason, ...@@ -233,15 +236,12 @@ void stream_manager::remove_input_path(stream_slot slot, error reason,
} }
inbound_path* stream_manager::get_inbound_path(stream_slot x) const noexcept { inbound_path* stream_manager::get_inbound_path(stream_slot x) const noexcept {
auto pred = [=](inbound_path* ptr) { auto pred = [=](inbound_path* ptr) { return ptr->slots.receiver == x; };
return ptr->slots.receiver == x;
};
auto e = inbound_paths_.end(); auto e = inbound_paths_.end();
auto i = std::find_if(inbound_paths_.begin(), e, pred); auto i = std::find_if(inbound_paths_.begin(), e, pred);
return i != e ? *i : nullptr; return i != e ? *i : nullptr;
} }
bool stream_manager::inbound_paths_idle() const noexcept { bool stream_manager::inbound_paths_idle() const noexcept {
auto f = [](inbound_path* x) { auto f = [](inbound_path* x) {
return x->up_to_date() && x->assigned_credit > 0; return x->up_to_date() && x->assigned_credit > 0;
......
This diff is collapsed.
...@@ -632,12 +632,12 @@ public: ...@@ -632,12 +632,12 @@ public:
// -- constructors, destructors, and assignment operators -------------------- // -- constructors, destructors, and assignment operators --------------------
static Config& init_config(Config& cfg) { static Config& init_config(Config& cfg) {
cfg.set("logger.file-verbosity", caf::atom("quiet"));
if (auto err = cfg.parse(caf::test::engine::argc(), if (auto err = cfg.parse(caf::test::engine::argc(),
caf::test::engine::argv())) caf::test::engine::argv()))
CAF_FAIL("failed to parse config: " << to_string(err)); CAF_FAIL("failed to parse config: " << to_string(err));
cfg.set("scheduler.policy", caf::atom("testing")); cfg.set("scheduler.policy", caf::atom("testing"));
cfg.set("logger.inline-output", true); cfg.set("logger.inline-output", true);
cfg.set("logger.file-verbosity", caf::atom("quiet"));
cfg.set("middleman.network-backend", caf::atom("testing")); cfg.set("middleman.network-backend", caf::atom("testing"));
cfg.set("middleman.manual-multiplexing", true); cfg.set("middleman.manual-multiplexing", true);
cfg.set("middleman.workers", size_t{0}); cfg.set("middleman.workers", size_t{0});
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment