diff options
Diffstat (limited to '3rdparty/asio/src/examples/cpp11/services')
5 files changed, 359 insertions, 0 deletions
diff --git a/3rdparty/asio/src/examples/cpp11/services/basic_logger.hpp b/3rdparty/asio/src/examples/cpp11/services/basic_logger.hpp new file mode 100644 index 00000000000..6e4d7a0b05d --- /dev/null +++ b/3rdparty/asio/src/examples/cpp11/services/basic_logger.hpp @@ -0,0 +1,78 @@ +// +// basic_logger.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef SERVICES_BASIC_LOGGER_HPP +#define SERVICES_BASIC_LOGGER_HPP + +#include <asio.hpp> +#include <string> + +namespace services { + +/// Class to provide simple logging functionality. Use the services::logger +/// typedef. +template <typename Service> +class basic_logger +{ +public: + /// The type of the service that will be used to provide timer operations. + typedef Service service_type; + + /// The native implementation type of the timer. + typedef typename service_type::impl_type impl_type; + + /// Constructor. + /** + * This constructor creates a logger. + * + * @param context The execution context used to locate the logger service. + * + * @param identifier An identifier for this logger. + */ + explicit basic_logger(asio::execution_context& context, + const std::string& identifier) + : service_(asio::use_service<Service>(context)), + impl_(service_.null()) + { + service_.create(impl_, identifier); + } + + basic_logger(const basic_logger&) = delete; + basic_logger& operator=(basic_logger&) = delete; + + /// Destructor. + ~basic_logger() + { + service_.destroy(impl_); + } + + /// Set the output file for all logger instances. + void use_file(const std::string& file) + { + service_.use_file(impl_, file); + } + + /// Log a message. + void log(const std::string& message) + { + service_.log(impl_, message); + } + +private: + /// The backend service implementation. + service_type& service_; + + /// The underlying native implementation. + impl_type impl_; +}; + +} // namespace services + +#endif // SERVICES_BASIC_LOGGER_HPP diff --git a/3rdparty/asio/src/examples/cpp11/services/daytime_client.cpp b/3rdparty/asio/src/examples/cpp11/services/daytime_client.cpp new file mode 100644 index 00000000000..360134f64c2 --- /dev/null +++ b/3rdparty/asio/src/examples/cpp11/services/daytime_client.cpp @@ -0,0 +1,101 @@ +// +// daytime_client.cpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include <asio.hpp> +#include <functional> +#include <iostream> +#include "logger.hpp" + +using asio::ip::tcp; + +char read_buffer[1024]; + +void read_handler(const asio::error_code& e, + std::size_t bytes_transferred, tcp::socket* s) +{ + if (!e) + { + std::cout.write(read_buffer, bytes_transferred); + + s->async_read_some(asio::buffer(read_buffer), + std::bind(read_handler, asio::placeholders::error, + asio::placeholders::bytes_transferred, s)); + } + else + { + asio::execution_context& context = asio::query( + s->get_executor(), asio::execution::context); + services::logger logger(context, "read_handler"); + + std::string msg = "Read error: "; + msg += e.message(); + logger.log(msg); + } +} + +void connect_handler(const asio::error_code& e, tcp::socket* s) +{ + asio::execution_context& context = asio::query( + s->get_executor(), asio::execution::context); + services::logger logger(context, "connect_handler"); + + if (!e) + { + logger.log("Connection established"); + + s->async_read_some(asio::buffer(read_buffer), + std::bind(read_handler, asio::placeholders::error, + asio::placeholders::bytes_transferred, s)); + } + else + { + std::string msg = "Unable to establish connection: "; + msg += e.message(); + logger.log(msg); + } +} + +int main(int argc, char* argv[]) +{ + try + { + if (argc != 2) + { + std::cerr << "Usage: daytime_client <host>" << std::endl; + return 1; + } + + asio::io_context io_context; + + // Set the name of the file that all logger instances will use. + services::logger logger(io_context, ""); + logger.use_file("log.txt"); + + // Resolve the address corresponding to the given host. + tcp::resolver resolver(io_context); + tcp::resolver::results_type endpoints = + resolver.resolve(argv[1], "daytime"); + + // Start an asynchronous connect. + tcp::socket socket(io_context); + asio::async_connect(socket, endpoints, + std::bind(connect_handler, + asio::placeholders::error, &socket)); + + // Run the io_context until all operations have finished. + io_context.run(); + } + catch (std::exception& e) + { + std::cerr << e.what() << std::endl; + } + + return 0; +} diff --git a/3rdparty/asio/src/examples/cpp11/services/logger.hpp b/3rdparty/asio/src/examples/cpp11/services/logger.hpp new file mode 100644 index 00000000000..2ab366c83c6 --- /dev/null +++ b/3rdparty/asio/src/examples/cpp11/services/logger.hpp @@ -0,0 +1,24 @@ +// +// logger.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef SERVICES_LOGGER_HPP +#define SERVICES_LOGGER_HPP + +#include "basic_logger.hpp" +#include "logger_service.hpp" + +namespace services { + +/// Typedef for typical logger usage. +typedef basic_logger<logger_service> logger; + +} // namespace services + +#endif // SERVICES_LOGGER_HPP diff --git a/3rdparty/asio/src/examples/cpp11/services/logger_service.cpp b/3rdparty/asio/src/examples/cpp11/services/logger_service.cpp new file mode 100644 index 00000000000..74d67c75241 --- /dev/null +++ b/3rdparty/asio/src/examples/cpp11/services/logger_service.cpp @@ -0,0 +1,11 @@ +// +// logger_service.cpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include "logger_service.hpp" diff --git a/3rdparty/asio/src/examples/cpp11/services/logger_service.hpp b/3rdparty/asio/src/examples/cpp11/services/logger_service.hpp new file mode 100644 index 00000000000..d0beaf1d6c2 --- /dev/null +++ b/3rdparty/asio/src/examples/cpp11/services/logger_service.hpp @@ -0,0 +1,145 @@ +// +// logger_service.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef SERVICES_LOGGER_SERVICE_HPP +#define SERVICES_LOGGER_SERVICE_HPP + +#include <asio.hpp> +#include <functional> +#include <fstream> +#include <sstream> +#include <string> +#include <thread> + +namespace services { + +/// Service implementation for the logger. +class logger_service + : public asio::execution_context::service +{ +public: + /// The type used to identify this service in the execution context. + typedef logger_service key_type; + + /// The backend implementation of a logger. + struct logger_impl + { + explicit logger_impl(const std::string& ident) : identifier(ident) {} + std::string identifier; + }; + + /// The type for an implementation of the logger. + typedef logger_impl* impl_type; + + /// Constructor creates a thread to run a private io_context. + logger_service(asio::execution_context& context) + : asio::execution_context::service(context), + work_io_context_(), + work_(asio::make_work_guard(work_io_context_)), + work_thread_([this]{ work_io_context_.run(); }) + { + } + + logger_service(const logger_service&) = delete; + logger_service& operator=(const logger_service&) = delete;; + + /// Destructor shuts down the private io_context. + ~logger_service() + { + /// Indicate that we have finished with the private io_context. Its + /// io_context::run() function will exit once all other work has completed. + work_.reset(); + if (work_thread_.joinable()) + work_thread_.join(); + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown() + { + } + + /// Return a null logger implementation. + impl_type null() const + { + return 0; + } + + /// Create a new logger implementation. + void create(impl_type& impl, const std::string& identifier) + { + impl = new logger_impl(identifier); + } + + /// Destroy a logger implementation. + void destroy(impl_type& impl) + { + delete impl; + impl = null(); + } + + /// Set the output file for the logger. The current implementation sets the + /// output file for all logger instances, and so the impl parameter is not + /// actually needed. It is retained here to illustrate how service functions + /// are typically defined. + void use_file(impl_type& /*impl*/, const std::string& file) + { + // Pass the work of opening the file to the background thread. + asio::post(work_io_context_, + std::bind(&logger_service::use_file_impl, this, file)); + } + + /// Log a message. + void log(impl_type& impl, const std::string& message) + { + // Format the text to be logged. + std::ostringstream os; + os << impl->identifier << ": " << message; + + // Pass the work of writing to the file to the background thread. + asio::post(work_io_context_, + std::bind(&logger_service::log_impl, this, os.str())); + } + +private: + /// Helper function used to open the output file from within the private + /// io_context's thread. + void use_file_impl(const std::string& file) + { + ofstream_.close(); + ofstream_.clear(); + ofstream_.open(file.c_str()); + } + + /// Helper function used to log a message from within the private io_context's + /// thread. + void log_impl(const std::string& text) + { + ofstream_ << text << std::endl; + } + + /// Private io_context used for performing logging operations. + asio::io_context work_io_context_; + + /// Work for the private io_context to perform. If we do not give the + /// io_context some work to do then the io_context::run() function will exit + /// immediately. + asio::executor_work_guard< + asio::io_context::executor_type> work_; + + /// Thread used for running the work io_context's run loop. + std::thread work_thread_; + + /// The file to which log messages will be written. + std::ofstream ofstream_; +}; + +} // namespace services + +#endif // SERVICES_LOGGER_SERVICE_HPP |