Simplify and unify callback design for both sync and async methods

This commit is contained in:
sangelovic
2019-04-03 00:05:20 +02:00
parent 5673a9bcf2
commit 08945acbc4
11 changed files with 116 additions and 237 deletions
+3 -7
View File
@@ -39,12 +39,13 @@ MethodRegistrator::MethodRegistrator(IObject& object, const std::string& methodN
}
MethodRegistrator::~MethodRegistrator() noexcept(false) // since C++11, destructors must
{ // explicitly be allowed to throw
{ // explicitly be allowed to throw
// Don't register the method if MethodRegistrator threw an exception in one of its methods
if (std::uncaught_exceptions() != exceptions_)
return;
SDBUS_THROW_ERROR_IF(interfaceName_.empty(), "DBus interface not specified when registering a DBus method", EINVAL);
SDBUS_THROW_ERROR_IF(!methodCallback_, "Method handler not specified when registering a DBus method", EINVAL);
// registerMethod() can throw. But as the MethodRegistrator shall always be used as an unnamed,
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
@@ -55,12 +56,7 @@ MethodRegistrator::~MethodRegistrator() noexcept(false) // since C++11, destruct
// Therefore, we can allow registerMethod() to throw even if we are in the destructor.
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
// to the exception thrown from here if the caller is a destructor itself.
if (syncCallback_)
object_.registerMethod(interfaceName_, methodName_, inputSignature_, outputSignature_, std::move(syncCallback_), flags_);
else if(asyncCallback_)
object_.registerMethod(interfaceName_, methodName_, inputSignature_, outputSignature_, std::move(asyncCallback_), flags_);
else
SDBUS_THROW_ERROR("Method handler not specified when registering a DBus method", EINVAL);
object_.registerMethod(interfaceName_, methodName_, inputSignature_, outputSignature_, std::move(methodCallback_), flags_);
}
SignalRegistrator::SignalRegistrator(IObject& object, const std::string& signalName)
+2 -31
View File
@@ -51,37 +51,8 @@ void Object::registerMethod( const std::string& interfaceName
{
SDBUS_THROW_ERROR_IF(!methodCallback, "Invalid method callback provided", EINVAL);
auto syncCallback = [callback = std::move(methodCallback)](MethodCall& msg)
{
auto reply = msg.createReply();
callback(msg, reply);
reply.send();
};
auto& interface = interfaces_[interfaceName];
InterfaceData::MethodData methodData{inputSignature, outputSignature, std::move(syncCallback), flags};
auto inserted = interface.methods_.emplace(methodName, std::move(methodData)).second;
SDBUS_THROW_ERROR_IF(!inserted, "Failed to register method: method already exists", EINVAL);
}
void Object::registerMethod( const std::string& interfaceName
, const std::string& methodName
, const std::string& inputSignature
, const std::string& outputSignature
, async_method_callback asyncMethodCallback
, Flags flags )
{
SDBUS_THROW_ERROR_IF(!asyncMethodCallback, "Invalid method callback provided", EINVAL);
auto asyncCallback = [callback = std::move(asyncMethodCallback)](MethodCall& msg)
{
MethodResult result{msg};
callback(std::move(msg), std::move(result));
};
auto& interface = interfaces_[interfaceName];
InterfaceData::MethodData methodData{inputSignature, outputSignature, std::move(asyncCallback), flags};
InterfaceData::MethodData methodData{inputSignature, outputSignature, std::move(methodCallback), flags};
auto inserted = interface.methods_.emplace(methodName, std::move(methodData)).second;
SDBUS_THROW_ERROR_IF(!inserted, "Failed to register method: method already exists", EINVAL);
@@ -245,7 +216,7 @@ int Object::sdbus_method_callback(sd_bus_message *sdbusMessage, void *userData,
try
{
callback(message);
callback(std::move(message));
}
catch (const sdbus::Error& e)
{
+1 -8
View File
@@ -52,13 +52,6 @@ namespace internal {
, method_callback methodCallback
, Flags flags ) override;
void registerMethod( const std::string& interfaceName
, const std::string& methodName
, const std::string& inputSignature
, const std::string& outputSignature
, async_method_callback asyncMethodCallback
, Flags flags ) override;
void registerSignal( const std::string& interfaceName
, const std::string& signalName
, const std::string& signature
@@ -93,7 +86,7 @@ namespace internal {
{
std::string inputArgs_;
std::string outputArgs_;
std::function<void(MethodCall&)> callback_;
method_callback callback_;
Flags flags_;
};
std::map<MethodName, MethodData> methods_;