summaryrefslogtreecommitdiff
path: root/doc/html/boost_asio/example/services
diff options
context:
space:
mode:
authorAnas Nashif <anas.nashif@intel.com>2012-10-30 12:57:26 -0700
committerAnas Nashif <anas.nashif@intel.com>2012-10-30 12:57:26 -0700
commit1a78a62555be32868418fe52f8e330c9d0f95d5a (patch)
treed3765a80e7d3b9640ec2e930743630cd6b9fce2b /doc/html/boost_asio/example/services
downloadboost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.gz
boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.bz2
boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.zip
Imported Upstream version 1.49.0upstream/1.49.0
Diffstat (limited to 'doc/html/boost_asio/example/services')
-rwxr-xr-xdoc/html/boost_asio/example/services/basic_logger.hpp83
-rwxr-xr-xdoc/html/boost_asio/example/services/daytime_client.cpp85
-rwxr-xr-xdoc/html/boost_asio/example/services/logger.hpp24
-rwxr-xr-xdoc/html/boost_asio/example/services/logger_service.cpp17
-rwxr-xr-xdoc/html/boost_asio/example/services/logger_service.hpp145
-rwxr-xr-xdoc/html/boost_asio/example/services/stream_socket_service.hpp351
6 files changed, 705 insertions, 0 deletions
diff --git a/doc/html/boost_asio/example/services/basic_logger.hpp b/doc/html/boost_asio/example/services/basic_logger.hpp
new file mode 100755
index 0000000000..1bc3540ca4
--- /dev/null
+++ b/doc/html/boost_asio/example/services/basic_logger.hpp
@@ -0,0 +1,83 @@
+//
+// basic_logger.hpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2012 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 <boost/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_service The io_service object used to locate the logger service.
+ *
+ * @param identifier An identifier for this logger.
+ */
+ explicit basic_logger(boost::asio::io_service& io_service,
+ const std::string& identifier)
+ : service_(boost::asio::use_service<Service>(io_service)),
+ impl_(service_.null())
+ {
+ service_.create(impl_, identifier);
+ }
+
+ /// Destructor.
+ ~basic_logger()
+ {
+ service_.destroy(impl_);
+ }
+
+ /// Get the io_service associated with the object.
+ boost::asio::io_service& get_io_service()
+ {
+ return service_.get_io_service();
+ }
+
+ /// 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/doc/html/boost_asio/example/services/daytime_client.cpp b/doc/html/boost_asio/example/services/daytime_client.cpp
new file mode 100755
index 0000000000..e54ee89c90
--- /dev/null
+++ b/doc/html/boost_asio/example/services/daytime_client.cpp
@@ -0,0 +1,85 @@
+//
+// daytime_client.cpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2012 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 <boost/asio.hpp>
+#include <boost/bind.hpp>
+#include <iostream>
+#include "logger.hpp"
+#include "stream_socket_service.hpp"
+
+typedef boost::asio::basic_stream_socket<boost::asio::ip::tcp,
+ services::stream_socket_service<boost::asio::ip::tcp> > debug_stream_socket;
+
+char read_buffer[1024];
+
+void read_handler(const boost::system::error_code& e,
+ std::size_t bytes_transferred, debug_stream_socket* s)
+{
+ if (!e)
+ {
+ std::cout.write(read_buffer, bytes_transferred);
+
+ s->async_read_some(boost::asio::buffer(read_buffer),
+ boost::bind(read_handler, boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred, s));
+ }
+}
+
+void connect_handler(const boost::system::error_code& e, debug_stream_socket* s)
+{
+ if (!e)
+ {
+ s->async_read_some(boost::asio::buffer(read_buffer),
+ boost::bind(read_handler, boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred, s));
+ }
+ else
+ {
+ std::cerr << e.message() << std::endl;
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: daytime_client <host>" << std::endl;
+ return 1;
+ }
+
+ boost::asio::io_service io_service;
+
+ // Set the name of the file that all logger instances will use.
+ services::logger logger(io_service, "");
+ logger.use_file("log.txt");
+
+ // Resolve the address corresponding to the given host.
+ boost::asio::ip::tcp::resolver resolver(io_service);
+ boost::asio::ip::tcp::resolver::query query(argv[1], "daytime");
+ boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
+
+ // Start an asynchronous connect.
+ debug_stream_socket socket(io_service);
+ boost::asio::async_connect(socket, iterator,
+ boost::bind(connect_handler,
+ boost::asio::placeholders::error, &socket));
+
+ // Run the io_service until all operations have finished.
+ io_service.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+
+ return 0;
+}
diff --git a/doc/html/boost_asio/example/services/logger.hpp b/doc/html/boost_asio/example/services/logger.hpp
new file mode 100755
index 0000000000..ef811d2a82
--- /dev/null
+++ b/doc/html/boost_asio/example/services/logger.hpp
@@ -0,0 +1,24 @@
+//
+// logger.hpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2012 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/doc/html/boost_asio/example/services/logger_service.cpp b/doc/html/boost_asio/example/services/logger_service.cpp
new file mode 100755
index 0000000000..ee43287ec6
--- /dev/null
+++ b/doc/html/boost_asio/example/services/logger_service.cpp
@@ -0,0 +1,17 @@
+//
+// logger_service.cpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2012 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 {
+
+boost::asio::io_service::id logger_service::id;
+
+} // namespace services
diff --git a/doc/html/boost_asio/example/services/logger_service.hpp b/doc/html/boost_asio/example/services/logger_service.hpp
new file mode 100755
index 0000000000..165018df06
--- /dev/null
+++ b/doc/html/boost_asio/example/services/logger_service.hpp
@@ -0,0 +1,145 @@
+//
+// logger_service.hpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2012 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 <boost/asio.hpp>
+#include <boost/thread/thread.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 boost::asio::io_service::service
+{
+public:
+ /// The unique service identifier.
+ static boost::asio::io_service::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_service.
+ logger_service(boost::asio::io_service& io_service)
+ : boost::asio::io_service::service(io_service),
+ work_io_service_(),
+ work_(new boost::asio::io_service::work(work_io_service_)),
+ work_thread_(new boost::thread(
+ boost::bind(&boost::asio::io_service::run, &work_io_service_)))
+ {
+ }
+
+ /// Destructor shuts down the private io_service.
+ ~logger_service()
+ {
+ /// Indicate that we have finished with the private io_service. Its
+ /// io_service::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.
+ work_io_service_.post(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.
+ work_io_service_.post(boost::bind(
+ &logger_service::log_impl, this, os.str()));
+ }
+
+private:
+ /// Helper function used to open the output file from within the private
+ /// io_service'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_service's
+ /// thread.
+ void log_impl(const std::string& text)
+ {
+ ofstream_ << text << std::endl;
+ }
+
+ /// Private io_service used for performing logging operations.
+ boost::asio::io_service work_io_service_;
+
+ /// Work for the private io_service to perform. If we do not give the
+ /// io_service some work to do then the io_service::run() function will exit
+ /// immediately.
+ boost::scoped_ptr<boost::asio::io_service::work> work_;
+
+ /// Thread used for running the work io_service's run loop.
+ boost::scoped_ptr<boost::thread> work_thread_;
+
+ /// The file to which log messages will be written.
+ std::ofstream ofstream_;
+};
+
+} // namespace services
+
+#endif // SERVICES_LOGGER_SERVICE_HPP
diff --git a/doc/html/boost_asio/example/services/stream_socket_service.hpp b/doc/html/boost_asio/example/services/stream_socket_service.hpp
new file mode 100755
index 0000000000..c63d6f43d1
--- /dev/null
+++ b/doc/html/boost_asio/example/services/stream_socket_service.hpp
@@ -0,0 +1,351 @@
+//
+// stream_socket_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2012 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_STREAM_SOCKET_SERVICE_HPP
+#define SERVICES_STREAM_SOCKET_SERVICE_HPP
+
+#include <boost/asio.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/lexical_cast.hpp>
+#include "logger.hpp"
+
+namespace services {
+
+/// Debugging stream socket service that wraps the normal stream socket service.
+template <typename Protocol>
+class stream_socket_service
+ : public boost::asio::io_service::service
+{
+private:
+ /// The type of the wrapped stream socket service.
+ typedef boost::asio::stream_socket_service<Protocol> service_impl_type;
+
+public:
+ /// The unique service identifier.
+ static boost::asio::io_service::id id;
+
+ /// The protocol type.
+ typedef Protocol protocol_type;
+
+ /// The endpoint type.
+ typedef typename Protocol::endpoint endpoint_type;
+
+ /// The implementation type of a stream socket.
+ typedef typename service_impl_type::implementation_type implementation_type;
+
+ /// The native type of a stream socket.
+ typedef typename service_impl_type::native_handle_type native_handle_type;
+
+ /// Construct a new stream socket service for the specified io_service.
+ explicit stream_socket_service(boost::asio::io_service& io_service)
+ : boost::asio::io_service::service(io_service),
+ service_impl_(boost::asio::use_service<service_impl_type>(io_service)),
+ logger_(io_service, "stream_socket")
+ {
+ }
+
+ /// Destroy all user-defined handler objects owned by the service.
+ void shutdown_service()
+ {
+ }
+
+ /// Construct a new stream socket implementation.
+ void construct(implementation_type& impl)
+ {
+ service_impl_.construct(impl);
+ }
+
+ /// Destroy a stream socket implementation.
+ void destroy(implementation_type& impl)
+ {
+ service_impl_.destroy(impl);
+ }
+
+ /// Open a new stream socket implementation.
+ boost::system::error_code open(implementation_type& impl,
+ const protocol_type& protocol, boost::system::error_code& ec)
+ {
+ logger_.log("Opening new socket");
+ return service_impl_.open(impl, protocol, ec);
+ }
+
+ /// Open a stream socket from an existing native socket.
+ boost::system::error_code assign(implementation_type& impl,
+ const protocol_type& protocol, const native_handle_type& native_socket,
+ boost::system::error_code& ec)
+ {
+ logger_.log("Assigning from a native socket");
+ return service_impl_.assign(impl, protocol, native_socket, ec);
+ }
+
+ /// Determine whether the socket is open.
+ bool is_open(const implementation_type& impl) const
+ {
+ logger_.log("Checking if socket is open");
+ return service_impl_.is_open(impl);
+ }
+
+ /// Close a stream socket implementation.
+ boost::system::error_code close(implementation_type& impl,
+ boost::system::error_code& ec)
+ {
+ logger_.log("Closing socket");
+ return service_impl_.close(impl, ec);
+ }
+
+ /// Determine whether the socket is at the out-of-band data mark.
+ bool at_mark(const implementation_type& impl,
+ boost::system::error_code& ec) const
+ {
+ logger_.log("Checking if socket is at out-of-band data mark");
+ return service_impl_.at_mark(impl, ec);
+ }
+
+ /// Determine the number of bytes available for reading.
+ std::size_t available(const implementation_type& impl,
+ boost::system::error_code& ec) const
+ {
+ logger_.log("Determining number of bytes available for reading");
+ return service_impl_.available(impl, ec);
+ }
+
+ /// Bind the stream socket to the specified local endpoint.
+ boost::system::error_code bind(implementation_type& impl,
+ const endpoint_type& endpoint, boost::system::error_code& ec)
+ {
+ logger_.log("Binding socket");
+ return service_impl_.bind(impl, endpoint, ec);
+ }
+
+ /// Connect the stream socket to the specified endpoint.
+ boost::system::error_code connect(implementation_type& impl,
+ const endpoint_type& peer_endpoint, boost::system::error_code& ec)
+ {
+ logger_.log("Connecting socket to " +
+ boost::lexical_cast<std::string>(peer_endpoint));
+ return service_impl_.connect(impl, peer_endpoint, ec);
+ }
+
+ /// Handler to wrap asynchronous connect completion.
+ template <typename Handler>
+ class connect_handler
+ {
+ public:
+ connect_handler(Handler h, logger& l)
+ : handler_(h),
+ logger_(l)
+ {
+ }
+
+ void operator()(const boost::system::error_code& e)
+ {
+ if (e)
+ {
+ std::string msg = "Asynchronous connect failed: ";
+ msg += e.message();
+ logger_.log(msg);
+ }
+ else
+ {
+ logger_.log("Asynchronous connect succeeded");
+ }
+
+ handler_(e);
+ }
+
+ private:
+ Handler handler_;
+ logger& logger_;
+ };
+
+ /// Start an asynchronous connect.
+ template <typename Handler>
+ void async_connect(implementation_type& impl,
+ const endpoint_type& peer_endpoint, Handler handler)
+ {
+ logger_.log("Starting asynchronous connect to " +
+ boost::lexical_cast<std::string>(peer_endpoint));
+ service_impl_.async_connect(impl, peer_endpoint,
+ connect_handler<Handler>(handler, logger_));
+ }
+
+ /// Set a socket option.
+ template <typename Option>
+ boost::system::error_code set_option(implementation_type& impl,
+ const Option& option, boost::system::error_code& ec)
+ {
+ logger_.log("Setting socket option");
+ return service_impl_.set_option(impl, option, ec);
+ }
+
+ /// Get a socket option.
+ template <typename Option>
+ boost::system::error_code get_option(const implementation_type& impl,
+ Option& option, boost::system::error_code& ec) const
+ {
+ logger_.log("Getting socket option");
+ return service_impl_.get_option(impl, option, ec);
+ }
+
+ /// Perform an IO control command on the socket.
+ template <typename IO_Control_Command>
+ boost::system::error_code io_control(implementation_type& impl,
+ IO_Control_Command& command, boost::system::error_code& ec)
+ {
+ logger_.log("Performing IO control command on socket");
+ return service_impl_.io_control(impl, command, ec);
+ }
+
+ /// Get the local endpoint.
+ endpoint_type local_endpoint(const implementation_type& impl,
+ boost::system::error_code& ec) const
+ {
+ logger_.log("Getting socket's local endpoint");
+ return service_impl_.local_endpoint(impl, ec);
+ }
+
+ /// Get the remote endpoint.
+ endpoint_type remote_endpoint(const implementation_type& impl,
+ boost::system::error_code& ec) const
+ {
+ logger_.log("Getting socket's remote endpoint");
+ return service_impl_.remote_endpoint(impl, ec);
+ }
+
+ /// Disable sends or receives on the socket.
+ boost::system::error_code shutdown(implementation_type& impl,
+ boost::asio::socket_base::shutdown_type what,
+ boost::system::error_code& ec)
+ {
+ logger_.log("Shutting down socket");
+ return service_impl_.shutdown(impl, what, ec);
+ }
+
+ /// Send the given data to the peer.
+ template <typename Const_Buffers>
+ std::size_t send(implementation_type& impl, const Const_Buffers& buffers,
+ boost::asio::socket_base::message_flags flags,
+ boost::system::error_code& ec)
+ {
+ logger_.log("Sending data on socket");
+ return service_impl_.send(impl, buffers, flags, ec);
+ }
+
+ /// Handler to wrap asynchronous send completion.
+ template <typename Handler>
+ class send_handler
+ {
+ public:
+ send_handler(Handler h, logger& l)
+ : handler_(h),
+ logger_(l)
+ {
+ }
+
+ void operator()(const boost::system::error_code& e,
+ std::size_t bytes_transferred)
+ {
+ if (e)
+ {
+ std::string msg = "Asynchronous send failed: ";
+ msg += e.message();
+ logger_.log(msg);
+ }
+ else
+ {
+ logger_.log("Asynchronous send succeeded");
+ }
+
+ handler_(e, bytes_transferred);
+ }
+
+ private:
+ Handler handler_;
+ logger& logger_;
+ };
+
+ /// Start an asynchronous send.
+ template <typename Const_Buffers, typename Handler>
+ void async_send(implementation_type& impl, const Const_Buffers& buffers,
+ boost::asio::socket_base::message_flags flags, Handler handler)
+ {
+ logger_.log("Starting asynchronous send");
+ service_impl_.async_send(impl, buffers, flags,
+ send_handler<Handler>(handler, logger_));
+ }
+
+ /// Receive some data from the peer.
+ template <typename Mutable_Buffers>
+ std::size_t receive(implementation_type& impl,
+ const Mutable_Buffers& buffers,
+ boost::asio::socket_base::message_flags flags,
+ boost::system::error_code& ec)
+ {
+ logger_.log("Receiving data on socket");
+ return service_impl_.receive(impl, buffers, flags, ec);
+ }
+
+ /// Handler to wrap asynchronous receive completion.
+ template <typename Handler>
+ class receive_handler
+ {
+ public:
+ receive_handler(Handler h, logger& l)
+ : handler_(h),
+ logger_(l)
+ {
+ }
+
+ void operator()(const boost::system::error_code& e,
+ std::size_t bytes_transferred)
+ {
+ if (e)
+ {
+ std::string msg = "Asynchronous receive failed: ";
+ msg += e.message();
+ logger_.log(msg);
+ }
+ else
+ {
+ logger_.log("Asynchronous receive succeeded");
+ }
+
+ handler_(e, bytes_transferred);
+ }
+
+ private:
+ Handler handler_;
+ logger& logger_;
+ };
+
+ /// Start an asynchronous receive.
+ template <typename Mutable_Buffers, typename Handler>
+ void async_receive(implementation_type& impl, const Mutable_Buffers& buffers,
+ boost::asio::socket_base::message_flags flags, Handler handler)
+ {
+ logger_.log("Starting asynchronous receive");
+ service_impl_.async_receive(impl, buffers, flags,
+ receive_handler<Handler>(handler, logger_));
+ }
+
+private:
+ /// The wrapped stream socket service.
+ service_impl_type& service_impl_;
+
+ /// The logger used for writing debug messages.
+ mutable logger logger_;
+};
+
+template <typename Protocol>
+boost::asio::io_service::id stream_socket_service<Protocol>::id;
+
+} // namespace services
+
+#endif // SERVICES_STREAM_SOCKET_SERVICE_HPP