diff options
author | Vernon Mauery <vernon.mauery@linux.intel.com> | 2019-05-07 16:53:50 -0700 |
---|---|---|
committer | Vernon Mauery <vernon.mauery@linux.intel.com> | 2019-05-10 08:11:23 -0700 |
commit | 37a5e61732ef93163b6f508eda046ff7b965314a (patch) | |
tree | 95ba2f4e875aacb23c002bf9aafceaf9dd24981c /sdbusplus/asio | |
parent | a564ac95dd5933d8e5660f3dd05c3076cca48c56 (diff) | |
download | sdbusplus-37a5e61732ef93163b6f508eda046ff7b965314a.tar.gz sdbusplus-37a5e61732ef93163b6f508eda046ff7b965314a.zip |
Change yield_method_call to be no-throw
The yield_method_call() would throw despite the inferred promise that it
would not, because the caller could attach an error_code to the yield
object. But that would only protect from the dbus method call itself.
When it came time to unpack the response, the read(...) method call
would throw if the received types did not match the expected types. Now,
the method forces you to pass in an error_code and it will always return
the appropriate error instead of throw.
Tested-by: run asio-example to see that it works as expected:
# /tmp/asio-example
voidBar() -> 42
async_send callback
error with async_send
async_method_call callback
/org/openbmc/control/bmc0
/org/openbmc/control/flash/bmc
fooYield(yield, 41)...
ipmiInterface:execute(61)
ipmi call returns OK!
fooYield(yield, 41)...
foo(41) -> 42
async call to Properties.Get serialized via yield OK!
foo(41) -> 42
yielding call to foo OK! (-> 42)
TestYieldFunction return 42
yielding call to foo OK! (-> 42)
yielding call to TestYieldFunction serialized via yield OK!
async call to Properties.Get serialized via yield OK!
*** tick ***
*** tock ***
*** tick ***
*** tick ***
*** tick ***
*** tick ***
*** tick ***
Change-Id: Iea43acd432107b4149f8e549310cfce2518cbc1d
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
Diffstat (limited to 'sdbusplus/asio')
-rw-r--r-- | sdbusplus/asio/connection.hpp | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/sdbusplus/asio/connection.hpp b/sdbusplus/asio/connection.hpp index 8590627..9b570be 100644 --- a/sdbusplus/asio/connection.hpp +++ b/sdbusplus/asio/connection.hpp @@ -149,9 +149,8 @@ class connection : public sdbusplus::bus::bus /** @brief Perform a yielding asynchronous method call, with input * parameter packing and return value unpacking * - * @param[in] yield - A yield context to async block upon. To catch errors - * for the call, call this function with 'yield[ec]', - * thus attaching an error code to the yield context + * @param[in] yield - A yield context to async block upon. + * @param[in] ec - an error code that will be set for any errors * @param[in] service - The service to call. * @param[in] objpath - The object's path for the call. * @param[in] interf - The object's interface to call. @@ -162,6 +161,7 @@ class connection : public sdbusplus::bus::bus */ template <typename... RetTypes, typename... InputArgs> auto yield_method_call(boost::asio::yield_context yield, + boost::system::error_code& ec, const std::string& service, const std::string& objpath, const std::string& interf, const std::string& method, @@ -170,7 +170,7 @@ class connection : public sdbusplus::bus::bus message::message m = new_method_call(service.c_str(), objpath.c_str(), interf.c_str(), method.c_str()); m.append(a...); - message::message r = async_send(m, yield); + message::message r = async_send(m, yield[ec]); if constexpr (sizeof...(RetTypes) == 0) { // void return @@ -187,8 +187,21 @@ class connection : public sdbusplus::bus::bus { // single item return utility::first_type<RetTypes...> responseData; - // this will throw if the signature of r != RetType - r.read(responseData); + // before attempting to read, check ec and bail on error + if (ec) + { + return responseData; + } + try + { + r.read(responseData); + } + catch (const std::exception& e) + { + ec = boost::system::errc::make_error_code( + boost::system::errc::invalid_argument); + // responseData will be default-constructed... + } return responseData; } } @@ -196,8 +209,21 @@ class connection : public sdbusplus::bus::bus { // tuple of things to return std::tuple<RetTypes...> responseData; - // this will throw if the signature of r != RetType - r.read(responseData); + // before attempting to read, check ec and bail on error + if (ec) + { + return responseData; + } + try + { + r.read(responseData); + } + catch (const std::exception& e) + { + ec = boost::system::errc::make_error_code( + boost::system::errc::invalid_argument); + // responseData will be default-constructed... + } return responseData; } } |