OK, the code I came up with as a solution is:
// Functor to help invoke the device method, inside a timed thread.
struct invoke_fn
{
void operator()(devices::server::CDeviceServer& server,
boost::promise<void>& boostPromise,
CDeviceClientRequest& request,
CDeviceServerResponse& response)
{
try
{
server.invoke(request, response);
boostPromise.set_value();
}
catch (devices::util::CDeviceException &e)
{
// Add any error to the response.
std::string message = devices::util::retrieveDeviceExceptionMessage(e);
response.set_errormessage(message);
}
catch (std::exception &e)
{
// Add any exception message to the response.
std::string message(e.what());
response.set_errormessage(message);
}
}
};
// Method to invoke a request with a timeout.
bool devices::server::CDeviceServer::invokeWithTimeout(CDeviceClientRequest& request,
CDeviceServerResponse& response)
{
// Retrieve the timeout from the device.
int timeout = getTimeout();
timeout += 500; // Add 500ms to cover invocation time.
// Invoke the request within a timed thread.
boost::promise<void> boostPromise;
boost::unique_future<void> boostFuture = boostPromise.get_future();
boost::thread boostThread([&]()
{
invoke_fn functor;
functor(*this,
boostPromise,
request,
response);
});
// The thread has timed out, if the future is not ready.
return (boostFuture.wait_for(boost::chrono::milliseconds(timeout))
==
boost::future_status::ready);
}