diff options
Diffstat (limited to '3rdparty/asio/src/examples/cpp03/services')
6 files changed, 377 insertions, 0 deletions
diff --git a/3rdparty/asio/src/examples/cpp03/services/.gitignore b/3rdparty/asio/src/examples/cpp03/services/.gitignore new file mode 100644 index 00000000000..701b1b85834 --- /dev/null +++ b/3rdparty/asio/src/examples/cpp03/services/.gitignore @@ -0,0 +1,11 @@ +.deps +.dirstamp +*.o +*.obj +*.exe +*_client +*.ilk +*.manifest +*.pdb +*.tds +log.txt diff --git a/3rdparty/asio/src/examples/cpp03/services/basic_logger.hpp b/3rdparty/asio/src/examples/cpp03/services/basic_logger.hpp new file mode 100644 index 00000000000..876086a2ecf --- /dev/null +++ b/3rdparty/asio/src/examples/cpp03/services/basic_logger.hpp @@ -0,0 +1,83 @@ +// +// basic_logger.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2016 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 <boost/noncopyable.hpp> +#include <string> + +namespace services { + +/// Class to provide simple logging functionality. Use the services::logger +/// typedef. +template <typename Service> +class basic_logger + : private boost::noncopyable +{ +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 io_context The io_context object used to locate the logger service. + * + * @param identifier An identifier for this logger. + */ + explicit basic_logger(asio::io_context& io_context, + const std::string& identifier) + : service_(asio::use_service<Service>(io_context)), + impl_(service_.null()) + { + service_.create(impl_, identifier); + } + + /// Destructor. + ~basic_logger() + { + service_.destroy(impl_); + } + + /// Get the io_context associated with the object. + asio::io_context& get_io_context() + { + return service_.get_io_context(); + } + + /// 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/cpp03/services/daytime_client.cpp b/3rdparty/asio/src/examples/cpp03/services/daytime_client.cpp new file mode 100644 index 00000000000..e0a6af9df6f --- /dev/null +++ b/3rdparty/asio/src/examples/cpp03/services/daytime_client.cpp @@ -0,0 +1,97 @@ +// +// daytime_client.cpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2016 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 <boost/bind.hpp> +#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), + boost::bind(read_handler, asio::placeholders::error, + asio::placeholders::bytes_transferred, s)); + } + else + { + services::logger logger(s->get_executor().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) +{ + services::logger logger(s->get_executor().context(), "connect_handler"); + + if (!e) + { + logger.log("Connection established"); + + s->async_read_some(asio::buffer(read_buffer), + boost::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, + boost::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/cpp03/services/logger.hpp b/3rdparty/asio/src/examples/cpp03/services/logger.hpp new file mode 100644 index 00000000000..41d17e6de10 --- /dev/null +++ b/3rdparty/asio/src/examples/cpp03/services/logger.hpp @@ -0,0 +1,24 @@ +// +// logger.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2016 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/cpp03/services/logger_service.cpp b/3rdparty/asio/src/examples/cpp03/services/logger_service.cpp new file mode 100644 index 00000000000..c3543e47f5a --- /dev/null +++ b/3rdparty/asio/src/examples/cpp03/services/logger_service.cpp @@ -0,0 +1,17 @@ +// +// logger_service.cpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2016 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" + +namespace services { + +asio::io_context::id logger_service::id; + +} // namespace services diff --git a/3rdparty/asio/src/examples/cpp03/services/logger_service.hpp b/3rdparty/asio/src/examples/cpp03/services/logger_service.hpp new file mode 100644 index 00000000000..9f175dffba3 --- /dev/null +++ b/3rdparty/asio/src/examples/cpp03/services/logger_service.hpp @@ -0,0 +1,145 @@ +// +// logger_service.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2016 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 <boost/bind.hpp> +#include <boost/date_time/posix_time/posix_time.hpp> +#include <boost/noncopyable.hpp> +#include <boost/scoped_ptr.hpp> +#include <fstream> +#include <sstream> +#include <string> + +namespace services { + +/// Service implementation for the logger. +class logger_service + : public asio::io_context::service +{ +public: + /// The unique service identifier. + static asio::io_context::id id; + + /// 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::io_context& io_context) + : asio::io_context::service(io_context), + work_io_context_(), + work_(asio::make_work_guard(work_io_context_)), + work_thread_(new asio::thread( + boost::bind(&asio::io_context::run, &work_io_context_))) + { + } + + /// 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_) + work_thread_->join(); + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + /// 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_, boost::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 opening the file to the background thread. + asio::post(work_io_context_, boost::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. + boost::scoped_ptr<asio::thread> work_thread_; + + /// The file to which log messages will be written. + std::ofstream ofstream_; +}; + +} // namespace services + +#endif // SERVICES_LOGGER_SERVICE_HPP |