diff --git a/docs/using-sdbus-c++.md b/docs/using-sdbus-c++.md index a0d8d60..8a65970 100644 --- a/docs/using-sdbus-c++.md +++ b/docs/using-sdbus-c++.md @@ -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 + + + + + + + + + + + + + + +``` + Using D-Bus properties ---------------------- diff --git a/tools/xml2cpp-codegen/ProxyGenerator.cpp b/tools/xml2cpp-codegen/ProxyGenerator.cpp index 98b7007..982d4f6 100644 --- a/tools/xml2cpp-codegen/ProxyGenerator.cpp +++ b/tools/xml2cpp-codegen/ProxyGenerator.cpp @@ -33,6 +33,7 @@ #include #include #include +#include using std::endl; @@ -130,6 +131,8 @@ std::string ProxyGenerator::processInterface(Node& interface) const std::tuple 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 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 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 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)