summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asio/src/examples/cpp03/invocation/prioritised_handlers.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asio/src/examples/cpp03/invocation/prioritised_handlers.cpp')
-rw-r--r--3rdparty/asio/src/examples/cpp03/invocation/prioritised_handlers.cpp162
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;
+}