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)