aboutsummaryrefslogtreecommitdiff
path: root/contrib/epee/include/net/levin_protocol_handler_async.h
diff options
context:
space:
mode:
authoranon <anon [at] nowhere>2021-01-19 17:09:32 +0000
committerselsta <selsta@sent.at>2021-01-19 18:15:30 +0100
commitdf2f00f44dc311896ac30892bc671dedf1739ee0 (patch)
tree21aabb455bed65d78b01e8110c7dfa76e2c43540 /contrib/epee/include/net/levin_protocol_handler_async.h
parentboosted_tcp_server: add segfault demo (diff)
downloadmonero-df2f00f44dc311896ac30892bc671dedf1739ee0.tar.xz
boosted_tcp_server: fix connection lifetime
Diffstat (limited to 'contrib/epee/include/net/levin_protocol_handler_async.h')
-rw-r--r--contrib/epee/include/net/levin_protocol_handler_async.h24
1 files changed, 19 insertions, 5 deletions
diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h
index ddde701ee..6e13c1b73 100644
--- a/contrib/epee/include/net/levin_protocol_handler_async.h
+++ b/contrib/epee/include/net/levin_protocol_handler_async.h
@@ -891,12 +891,22 @@ template<class t_connection_context> template<class callback_t>
bool async_protocol_handler_config<t_connection_context>::foreach_connection(const callback_t &cb)
{
CRITICAL_REGION_LOCAL(m_connects_lock);
- for(auto& c: m_connects)
- {
- async_protocol_handler<t_connection_context>* aph = c.second;
- if(!cb(aph->get_context_ref()))
+ std::vector<typename connections_map::mapped_type> conn;
+ conn.reserve(m_connects.size());
+
+ auto scope_exit_handler = misc_utils::create_scope_leave_handler([&conn]{
+ for (auto &aph: conn)
+ aph->finish_outer_call();
+ });
+
+ for (auto &e: m_connects)
+ if (e.second->start_outer_call())
+ conn.push_back(e.second);
+
+ for (auto &aph: conn)
+ if (!cb(aph->get_context_ref()))
return false;
- }
+
return true;
}
//------------------------------------------------------------------------------------------
@@ -907,6 +917,10 @@ bool async_protocol_handler_config<t_connection_context>::for_connection(const b
async_protocol_handler<t_connection_context>* aph = find_connection(connection_id);
if (!aph)
return false;
+ if (!aph->start_outer_call())
+ return false;
+ auto scope_exit_handler = misc_utils::create_scope_leave_handler(
+ boost::bind(&async_protocol_handler<t_connection_context>::finish_outer_call, aph));
if(!cb(aph->get_context_ref()))
return false;
return true;