codegen: Support chrono literal timeout by ProxyGenerator

Allow to use human readable chrono literals to specify method call
timeout. The change is backward compatbile - if no unit is provided,
the fallback is "us".

Example:
<annotation name="org.freedesktop.DBus.Method.Timeout" value="500ms"/>
This commit is contained in:
Lukasz Marcul
2021-11-13 14:59:25 +01:00
committed by Stanislav Angelovič
parent b01db13ff7
commit 442670ec18
2 changed files with 35 additions and 1 deletions

View File

@ -1156,6 +1156,27 @@ So in the specific example above, the stub generator will generate a `Concatenat
For a real example of a client-side asynchronous D-Bus method, please look at sdbus-c++ [stress tests](/tests/stresstests).
## Method call timeout
Annotate the element with `org.freedesktop.DBus.Method.Timeout` in order to specify the timeout value for the method call. The value should be a number of microseconds or number with duration literal (`us`/`ms`/`s`/`min`). Optionally combine it with `org.freedesktop.DBus.Method.Async`.
```xml
<?xml version="1.0" encoding="UTF-8"?>
<node>
<interface name="org.bluez.Device1">
<method name="Connect">
<annotation name="org.freedesktop.DBus.Method.Async" value="client"/>
<annotation name="org.freedesktop.DBus.Method.Timeout" value="3000ms"/>
</method>
<method name="Disconnect">
<annotation name="org.freedesktop.DBus.Method.Async" value="client"/>
<annotation name="org.freedesktop.DBus.Method.Timeout" value="2000000"/> <!-- 2000000us -->
</method>
</interface>
</node>
```
Using D-Bus properties
----------------------

View File

@ -33,6 +33,7 @@
#include <cstdlib>
#include <algorithm>
#include <iterator>
#include <regex>
using std::endl;
@ -130,6 +131,8 @@ std::string ProxyGenerator::processInterface(Node& interface) const
std::tuple<std::string, std::string> ProxyGenerator::processMethods(const Nodes& methods) const
{
const std::regex patternTimeout{R"(^(\d+)(min|s|ms|us)?$)"};
std::ostringstream definitionSS, asyncDeclarationSS;
for (const auto& method : methods)
@ -143,6 +146,7 @@ std::tuple<std::string, std::string> ProxyGenerator::processMethods(const Nodes&
bool dontExpectReply{false};
bool async{false};
std::string timeoutValue;
std::smatch smTimeout;
Nodes annotations = (*method)["annotation"];
for (const auto& annotation : annotations)
@ -168,6 +172,13 @@ std::tuple<std::string, std::string> ProxyGenerator::processMethods(const Nodes&
timeoutValue.clear();
}
if (!timeoutValue.empty() && !std::regex_match(timeoutValue, smTimeout, patternTimeout))
{
std::cerr << "Function: " << name << ": ";
std::cerr << "Option 'org.freedesktop.DBus.Method.Timeout' has unsupported timeout value! Option ignored..." << std::endl;
timeoutValue.clear();
}
auto retType = outArgsToType(outArgs);
std::string inArgStr, inArgTypeStr;
std::tie(inArgStr, inArgTypeStr, std::ignore, std::ignore) = argsToNamesAndTypes(inArgs);
@ -193,7 +204,9 @@ std::tuple<std::string, std::string> ProxyGenerator::processMethods(const Nodes&
if (!timeoutValue.empty())
{
definitionSS << ".withTimeout(" << timeoutValue << "us)";
const auto val = smTimeout.str(1);
const auto unit = smTimeout.str(2);
definitionSS << ".withTimeout(" << val << (unit.empty() ? "us" : unit) << ")";
}
if (inArgs.size() > 0)