blob: 9d612e57212fa67b8abab0aa9e032d186b22b6a3 [file] [log] [blame]
#pragma once
#include <cerrno>
#include <chrono>
#include <cstdio>
#include <exception>
#include <functional>
#include <sdeventplus/exception.hpp>
#include <stdexcept>
#include <stdplus/util/cexec.hpp>
#include <utility>
namespace sdeventplus
{
// Defined by systemd taking uint64_t usec params
using SdEventDuration =
std::chrono::duration<uint64_t, std::chrono::microseconds::period>;
namespace internal
{
/** @brief Handle sd_event callback exception gracefully
* @details A generic wrapper that turns exceptions into
* error messages and return codes.
*/
template <typename... Args>
inline int performCallback(const char* name, Args&&... args)
{
try
{
std::invoke(std::forward<Args>(args)...);
return 0;
}
catch (const std::system_error& e)
{
fprintf(stderr, "sdeventplus: %s: %s\n", name, e.what());
return -e.code().value();
}
catch (const std::exception& e)
{
fprintf(stderr, "sdeventplus: %s: %s\n", name, e.what());
return -ENOSYS;
}
catch (...)
{
fprintf(stderr, "sdeventplus: %s: Unknown error\n", name);
return -ENOSYS;
}
}
/** @brief Constructs an SdEventError for stdplus cexec
*/
inline SdEventError makeError(int error, const char* msg)
{
return SdEventError(error, msg);
}
template <typename... Args>
inline auto callCheck(const char* msg, Args&&... args)
{
return stdplus::util::callCheckRet<makeError, Args...>(
msg, std::forward<Args>(args)...);
}
} // namespace internal
} // namespace sdeventplus