break out boost coroutines async_send
async_send is a method that was attempted to be shared between coroutine
and non-coroutine cases. Unfortunately to have this code sharing
requires a very expensive template, boost::asio::initiate. While this
template is great for generalizing, it results in a template
instantiation per call site, which doesn't scale well at build time in
things like bmcweb, where we have 400+ async_method_call sites.
This commit breaks out async_send into async_send and async_send_yield,
which allows using concrete callback and return types, thus avoiding
the multiple template instantiations.
Tested: ClangBuildAnalyzer shows that this template is no longer one of
the longest to instantiate.
Change-Id: Ic8f226e5be71f05c5f5dcb73eb51e6094dc704eb
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/example/asio-example.cpp b/example/asio-example.cpp
index 145e87a..f7f0522 100644
--- a/example/asio-example.cpp
+++ b/example/asio-example.cpp
@@ -108,7 +108,7 @@
std::vector<uint8_t> commandData = {4, 3, 2, 1};
method.append(netFn, lun, cmd, commandData, options);
boost::system::error_code ec;
- sdbusplus::message_t reply = conn->async_send(method, yield[ec]);
+ sdbusplus::message_t reply = conn->async_send_yield(method, yield[ec]);
std::tuple<uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>>
tupleOut;
try
diff --git a/include/sdbusplus/asio/connection.hpp b/include/sdbusplus/asio/connection.hpp
index 9a75b5c..d48d721 100644
--- a/include/sdbusplus/asio/connection.hpp
+++ b/include/sdbusplus/asio/connection.hpp
@@ -82,21 +82,26 @@
* @param[in] timeout - The timeout in microseconds
*
*/
- template <typename CompletionToken>
- inline auto async_send(message_t& m, CompletionToken&& token,
+
+ using callback_t = void(boost::system::error_code, message_t&);
+ using send_function = std::move_only_function<callback_t>;
+ inline void async_send(message_t& m, send_function&& callback,
uint64_t timeout = 0)
{
-#ifdef SDBUSPLUS_DISABLE_BOOST_COROUTINES
- constexpr bool is_yield = false;
-#else
- constexpr bool is_yield =
- std::is_same_v<CompletionToken, boost::asio::yield_context>;
-#endif
- using return_t = std::conditional_t<is_yield, message_t, message_t&>;
- using callback_t = void(boost::system::error_code, return_t);
- return boost::asio::async_initiate<CompletionToken, callback_t>(
+ boost::asio::async_initiate<send_function, callback_t>(
+ detail::async_send_handler(get(), m, timeout), callback);
+ }
+#ifndef SDBUSPLUS_DISABLE_BOOST_COROUTINES
+ inline auto async_send_yield(message_t& m,
+ boost::asio::yield_context&& token,
+ uint64_t timeout = 0)
+ {
+ using yield_callback_t = void(boost::system::error_code, message_t);
+ return boost::asio::async_initiate<boost::asio::yield_context,
+ yield_callback_t>(
detail::async_send_handler(get(), m, timeout), token);
}
+#endif
/** @brief Perform an asynchronous method call, with input parameter packing
* and return value unpacking.
@@ -270,7 +275,7 @@
if (!ec)
{
message_t r;
- r = async_send(m, yield[ec]);
+ r = async_send_yield(m, yield[ec]);
try
{
return r.unpack<RetTypes...>();