diff options
Diffstat (limited to '3rdparty/asio/src/examples/cpp03/invocation/prioritised_handlers.cpp')
-rw-r--r-- | 3rdparty/asio/src/examples/cpp03/invocation/prioritised_handlers.cpp | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/3rdparty/asio/src/examples/cpp03/invocation/prioritised_handlers.cpp b/3rdparty/asio/src/examples/cpp03/invocation/prioritised_handlers.cpp new file mode 100644 index 00000000000..73897946966 --- /dev/null +++ b/3rdparty/asio/src/examples/cpp03/invocation/prioritised_handlers.cpp @@ -0,0 +1,162 @@ +// +// prioritised_handlers.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/function.hpp> +#include <iostream> +#include <queue> + +using asio::ip::tcp; + +class handler_priority_queue +{ +public: + void add(int priority, boost::function<void()> function) + { + handlers_.push(queued_handler(priority, function)); + } + + void execute_all() + { + while (!handlers_.empty()) + { + queued_handler handler = handlers_.top(); + handler.execute(); + handlers_.pop(); + } + } + + // A generic wrapper class for handlers to allow the invocation to be hooked. + template <typename Handler> + class wrapped_handler + { + public: + wrapped_handler(handler_priority_queue& q, int p, Handler h) + : queue_(q), priority_(p), handler_(h) + { + } + + void operator()() + { + handler_(); + } + + template <typename Arg1> + void operator()(Arg1 arg1) + { + handler_(arg1); + } + + template <typename Arg1, typename Arg2> + void operator()(Arg1 arg1, Arg2 arg2) + { + handler_(arg1, arg2); + } + + //private: + handler_priority_queue& queue_; + int priority_; + Handler handler_; + }; + + template <typename Handler> + wrapped_handler<Handler> wrap(int priority, Handler handler) + { + return wrapped_handler<Handler>(*this, priority, handler); + } + +private: + class queued_handler + { + public: + queued_handler(int p, boost::function<void()> f) + : priority_(p), function_(f) + { + } + + void execute() + { + function_(); + } + + friend bool operator<(const queued_handler& a, + const queued_handler& b) + { + return a.priority_ < b.priority_; + } + + private: + int priority_; + boost::function<void()> function_; + }; + + std::priority_queue<queued_handler> handlers_; +}; + +// Custom invocation hook for wrapped handlers. +template <typename Function, typename Handler> +void asio_handler_invoke(Function f, + handler_priority_queue::wrapped_handler<Handler>* h) +{ + h->queue_.add(h->priority_, f); +} + +//---------------------------------------------------------------------- + +void high_priority_handler(const asio::error_code& /*ec*/) +{ + std::cout << "High priority handler\n"; +} + +void middle_priority_handler(const asio::error_code& /*ec*/) +{ + std::cout << "Middle priority handler\n"; +} + +void low_priority_handler() +{ + std::cout << "Low priority handler\n"; +} + +int main() +{ + asio::io_context io_context; + + handler_priority_queue pri_queue; + + // Post a completion handler to be run immediately. + asio::post(io_context, pri_queue.wrap(0, low_priority_handler)); + + // Start an asynchronous accept that will complete immediately. + tcp::endpoint endpoint(asio::ip::address_v4::loopback(), 0); + tcp::acceptor acceptor(io_context, endpoint); + tcp::socket server_socket(io_context); + acceptor.async_accept(server_socket, + pri_queue.wrap(100, high_priority_handler)); + tcp::socket client_socket(io_context); + client_socket.connect(acceptor.local_endpoint()); + + // Set a deadline timer to expire immediately. + asio::deadline_timer timer(io_context); + timer.expires_at(boost::posix_time::neg_infin); + timer.async_wait(pri_queue.wrap(42, middle_priority_handler)); + + while (io_context.run_one()) + { + // The custom invocation hook adds the handlers to the priority queue + // rather than executing them from within the poll_one() call. + while (io_context.poll_one()) + ; + + pri_queue.execute_all(); + } + + return 0; +} |