summaryrefslogtreecommitdiffstats
path: root/sdbusplus/asio
diff options
context:
space:
mode:
authorVernon Mauery <vernon.mauery@linux.intel.com>2019-05-07 16:53:50 -0700
committerVernon Mauery <vernon.mauery@linux.intel.com>2019-05-10 08:11:23 -0700
commit37a5e61732ef93163b6f508eda046ff7b965314a (patch)
tree95ba2f4e875aacb23c002bf9aafceaf9dd24981c /sdbusplus/asio
parenta564ac95dd5933d8e5660f3dd05c3076cca48c56 (diff)
downloadsdbusplus-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.hpp42
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;
}
}
OpenPOWER on IntegriCloud