From cb092d124eb33f986098caa9578fc75f4960cc70 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Thu, 2 Oct 2025 12:15:35 -0500 Subject: [PATCH] move timeout to utils --- .../src/comm/packet/packet_client.cpp | 8 +- .../src/comm/packet/packet_server.cpp | 10 +- .../src/drives/winfsp/winfsp_drive.cpp | 2 +- .../include/utils/timeout.hpp | 116 +++++++------ .../src/utils/timeout.cpp | 164 +++++++++--------- 5 files changed, 152 insertions(+), 148 deletions(-) rename {repertory/librepertory => support}/include/utils/timeout.hpp (95%) rename {repertory/librepertory => support}/src/utils/timeout.cpp (94%) diff --git a/repertory/librepertory/src/comm/packet/packet_client.cpp b/repertory/librepertory/src/comm/packet/packet_client.cpp index e9a2fd9c..78a78ad9 100644 --- a/repertory/librepertory/src/comm/packet/packet_client.cpp +++ b/repertory/librepertory/src/comm/packet/packet_client.cpp @@ -93,7 +93,7 @@ auto packet_client::check_version(std::uint32_t client_version, boost::asio::io_context ctx{}; client cli(ctx); - timeout connect_timeout( + utils::timeout connect_timeout( [&cli]() { event_system::instance().raise("connect", function_name); @@ -131,7 +131,7 @@ auto packet_client::connect(client &cli) -> bool { REPERTORY_USES_FUNCTION_NAME(); try { - timeout connect_timeout( + utils::timeout connect_timeout( [&cli]() { event_system::instance().raise("connect", function_name); @@ -257,7 +257,7 @@ void packet_client::put_client(std::shared_ptr &cli) { void packet_client::read_data(client &cli, data_buffer &buffer) const { REPERTORY_USES_FUNCTION_NAME(); - timeout read_timeout( + utils::timeout read_timeout( [&cli]() { event_system::instance().raise("response", function_name); @@ -401,7 +401,7 @@ auto packet_client::send(std::string_view method, packet &request, void packet_client::write_data(client &cli, const packet &request) const { REPERTORY_USES_FUNCTION_NAME(); - timeout write_timeout( + utils::timeout write_timeout( [&cli]() { event_system::instance().raise("request", function_name); diff --git a/repertory/librepertory/src/comm/packet/packet_server.cpp b/repertory/librepertory/src/comm/packet/packet_server.cpp index f9c85776..3e4e6530 100644 --- a/repertory/librepertory/src/comm/packet/packet_server.cpp +++ b/repertory/librepertory/src/comm/packet/packet_server.cpp @@ -114,8 +114,9 @@ auto packet_server::handshake(std::shared_ptr conn) const -> bool { } }; - timeout write_timeout(timeout_handler, std::chrono::milliseconds( - server_handshake_timeout_ms)); + utils::timeout write_timeout( + timeout_handler, + std::chrono::milliseconds(server_handshake_timeout_ms)); auto bytes_written = boost::asio::write( conn->socket, boost::asio::buffer(boost::asio::buffer(buffer))); @@ -124,8 +125,9 @@ auto packet_server::handshake(std::shared_ptr conn) const -> bool { if (bytes_written == buffer.size()) { conn->buffer.resize(to_read); - timeout read_timeout(timeout_handler, std::chrono::milliseconds( - server_handshake_timeout_ms)); + utils::timeout read_timeout( + timeout_handler, + std::chrono::milliseconds(server_handshake_timeout_ms)); std::uint32_t total_read{}; while ((total_read < to_read) && conn->socket.is_open()) { diff --git a/repertory/librepertory/src/drives/winfsp/winfsp_drive.cpp b/repertory/librepertory/src/drives/winfsp/winfsp_drive.cpp index 4d067257..31ff659a 100644 --- a/repertory/librepertory/src/drives/winfsp/winfsp_drive.cpp +++ b/repertory/librepertory/src/drives/winfsp/winfsp_drive.cpp @@ -136,7 +136,7 @@ auto winfsp_drive::winfsp_service::OnStart(ULONG /*Argc*/, PWSTR * /*Argv*/) auto winfsp_drive::winfsp_service::OnStop() -> NTSTATUS { REPERTORY_USES_FUNCTION_NAME(); - timeout stop_timeout( + utils::timeout stop_timeout( []() { event_system::instance().raise(function_name); app_config::set_stop_requested(); diff --git a/repertory/librepertory/include/utils/timeout.hpp b/support/include/utils/timeout.hpp similarity index 95% rename from repertory/librepertory/include/utils/timeout.hpp rename to support/include/utils/timeout.hpp index c55b7c95..f7498e43 100644 --- a/repertory/librepertory/include/utils/timeout.hpp +++ b/support/include/utils/timeout.hpp @@ -1,57 +1,59 @@ -/* - Copyright <2018-2025> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ -#ifndef REPERTORY_INCLUDE_UTILS_TIMEOUT_HPP_ -#define REPERTORY_INCLUDE_UTILS_TIMEOUT_HPP_ - -namespace repertory { -class timeout final { -public: - using callback_t = std::function; - -public: - timeout(const timeout &) noexcept = delete; - timeout(timeout &&) noexcept = delete; - auto operator=(const timeout &) noexcept -> timeout & = delete; - auto operator=(timeout &&) noexcept -> timeout & = delete; - -public: - timeout(callback_t timeout_callback, - std::chrono::system_clock::duration duration); - - ~timeout(); - -private: - std::chrono::system_clock::duration duration_; - callback_t timeout_callback_; - std::atomic timeout_killed_{false}; - std::unique_ptr timeout_thread_{nullptr}; - std::mutex timeout_mutex_; - std::condition_variable timeout_notify_; - -public: - void disable(); - - void reset(); -}; -} // namespace repertory - -#endif // REPERTORY_INCLUDE_UTILS_TIMEOUT_HPP_ +/* + Copyright <2018-2025> + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +#ifndef REPERTORY_INCLUDE_UTILS_TIMEOUT_HPP_ +#define REPERTORY_INCLUDE_UTILS_TIMEOUT_HPP_ + +#include "utils/config.hpp" + +namespace repertory::utils { +class timeout final { +public: + using callback_t = std::function; + +public: + timeout(const timeout &) noexcept = delete; + timeout(timeout &&) noexcept = delete; + auto operator=(const timeout &) noexcept -> timeout & = delete; + auto operator=(timeout &&) noexcept -> timeout & = delete; + +public: + timeout(callback_t timeout_callback, + std::chrono::system_clock::duration duration); + + ~timeout(); + +private: + std::chrono::system_clock::duration duration_; + callback_t timeout_callback_; + std::atomic timeout_killed_{false}; + std::unique_ptr timeout_thread_{nullptr}; + std::mutex timeout_mutex_; + std::condition_variable timeout_notify_; + +public: + void disable(); + + void reset(); +}; +} // namespace repertory::utils + +#endif // REPERTORY_INCLUDE_UTILS_TIMEOUT_HPP_ diff --git a/repertory/librepertory/src/utils/timeout.cpp b/support/src/utils/timeout.cpp similarity index 94% rename from repertory/librepertory/src/utils/timeout.cpp rename to support/src/utils/timeout.cpp index d1d066cf..947f2229 100644 --- a/repertory/librepertory/src/utils/timeout.cpp +++ b/support/src/utils/timeout.cpp @@ -1,82 +1,82 @@ -/* - Copyright <2018-2025> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ -#include "utils/timeout.hpp" - -namespace repertory { -timeout::timeout(callback_t timeout_callback, - std::chrono::system_clock::duration duration) - : duration_(duration), - timeout_callback_(std::move(timeout_callback)), - timeout_killed_(duration <= std::chrono::system_clock::duration::zero()) { - if (timeout_killed_) { - return; - } - - timeout_thread_ = std::make_unique([this]() { - std::unique_lock loc_lock(timeout_mutex_); - - while (not timeout_killed_) { - auto res = timeout_notify_.wait_for(loc_lock, duration_); - if (res != std::cv_status::timeout) { - continue; - } - - if (timeout_killed_) { - return; - } - - timeout_killed_ = true; - loc_lock.unlock(); - - try { - timeout_callback_(); - } catch (...) { - } - return; - } - }); -} - -timeout::~timeout() { disable(); } - -void timeout::disable() { - unique_mutex_lock lock(timeout_mutex_); - std::unique_ptr timeout_thread{nullptr}; - std::swap(timeout_thread, timeout_thread_); - - if (not timeout_thread) { - timeout_notify_.notify_all(); - return; - } - - timeout_killed_ = true; - timeout_notify_.notify_all(); - lock.unlock(); - - timeout_thread->join(); -} - -void timeout::reset() { - mutex_lock lock(timeout_mutex_); - timeout_notify_.notify_all(); -} -} // namespace repertory +/* + Copyright <2018-2025> + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +#include "utils/timeout.hpp" + +namespace repertory::utils { +timeout::timeout(callback_t timeout_callback, + std::chrono::system_clock::duration duration) + : duration_(duration), + timeout_callback_(std::move(timeout_callback)), + timeout_killed_(duration <= std::chrono::system_clock::duration::zero()) { + if (timeout_killed_) { + return; + } + + timeout_thread_ = std::make_unique([this]() { + std::unique_lock loc_lock(timeout_mutex_); + + while (not timeout_killed_) { + auto res = timeout_notify_.wait_for(loc_lock, duration_); + if (res != std::cv_status::timeout) { + continue; + } + + if (timeout_killed_) { + return; + } + + timeout_killed_ = true; + loc_lock.unlock(); + + try { + timeout_callback_(); + } catch (...) { + } + return; + } + }); +} + +timeout::~timeout() { disable(); } + +void timeout::disable() { + unique_mutex_lock lock(timeout_mutex_); + std::unique_ptr timeout_thread{nullptr}; + std::swap(timeout_thread, timeout_thread_); + + if (not timeout_thread) { + timeout_notify_.notify_all(); + return; + } + + timeout_killed_ = true; + timeout_notify_.notify_all(); + lock.unlock(); + + timeout_thread->join(); +} + +void timeout::reset() { + mutex_lock lock(timeout_mutex_); + timeout_notify_.notify_all(); +} +} // namespace repertory::utils