]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/asio/example/cpp03/invocation/prioritised_handlers.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / asio / example / cpp03 / invocation / prioritised_handlers.cpp
CommitLineData
7c673cae
FG
1//
2// prioritised_handlers.cpp
3// ~~~~~~~~~~~~~~~~~~~~~~~~
4//
b32b8144 5// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7c673cae
FG
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11#include <boost/asio.hpp>
12#include <boost/function.hpp>
13#include <iostream>
14#include <queue>
15
16using boost::asio::ip::tcp;
17
b32b8144 18class handler_priority_queue : boost::asio::execution_context
7c673cae
FG
19{
20public:
21 void add(int priority, boost::function<void()> function)
22 {
23 handlers_.push(queued_handler(priority, function));
24 }
25
26 void execute_all()
27 {
28 while (!handlers_.empty())
29 {
30 queued_handler handler = handlers_.top();
31 handler.execute();
32 handlers_.pop();
33 }
34 }
35
b32b8144 36 class executor
7c673cae
FG
37 {
38 public:
b32b8144
FG
39 executor(handler_priority_queue& q, int p)
40 : context_(q), priority_(p)
41 {
42 }
43
44 handler_priority_queue& context() const
7c673cae 45 {
b32b8144 46 return context_;
7c673cae
FG
47 }
48
b32b8144
FG
49 template <typename Function, typename Allocator>
50 void dispatch(const Function& f, const Allocator&) const
7c673cae 51 {
b32b8144 52 context_.add(priority_, f);
7c673cae
FG
53 }
54
b32b8144
FG
55 template <typename Function, typename Allocator>
56 void post(const Function& f, const Allocator&) const
7c673cae 57 {
b32b8144 58 context_.add(priority_, f);
7c673cae
FG
59 }
60
b32b8144
FG
61 template <typename Function, typename Allocator>
62 void defer(const Function& f, const Allocator&) const
63 {
64 context_.add(priority_, f);
65 }
66
67 void on_work_started() const {}
68 void on_work_finished() const {}
69
70 bool operator==(const executor& other) const
7c673cae 71 {
b32b8144 72 return &context_ == &other.context_ && priority_ == other.priority_;
7c673cae
FG
73 }
74
b32b8144
FG
75 bool operator!=(const executor& other) const
76 {
77 return !operator==(other);
78 }
79
80 private:
81 handler_priority_queue& context_;
7c673cae 82 int priority_;
7c673cae
FG
83 };
84
85 template <typename Handler>
b32b8144
FG
86 boost::asio::executor_binder<Handler, executor>
87 wrap(int priority, Handler handler)
7c673cae 88 {
b32b8144 89 return boost::asio::bind_executor(executor(*this, priority), handler);
7c673cae
FG
90 }
91
92private:
93 class queued_handler
94 {
95 public:
96 queued_handler(int p, boost::function<void()> f)
97 : priority_(p), function_(f)
98 {
99 }
100
101 void execute()
102 {
103 function_();
104 }
105
106 friend bool operator<(const queued_handler& a,
107 const queued_handler& b)
108 {
109 return a.priority_ < b.priority_;
110 }
111
112 private:
113 int priority_;
114 boost::function<void()> function_;
115 };
116
117 std::priority_queue<queued_handler> handlers_;
118};
119
7c673cae
FG
120//----------------------------------------------------------------------
121
122void high_priority_handler(const boost::system::error_code& /*ec*/)
123{
124 std::cout << "High priority handler\n";
125}
126
127void middle_priority_handler(const boost::system::error_code& /*ec*/)
128{
129 std::cout << "Middle priority handler\n";
130}
131
132void low_priority_handler()
133{
134 std::cout << "Low priority handler\n";
135}
136
137int main()
138{
b32b8144 139 boost::asio::io_context io_context;
7c673cae
FG
140
141 handler_priority_queue pri_queue;
142
143 // Post a completion handler to be run immediately.
b32b8144 144 boost::asio::post(io_context, pri_queue.wrap(0, low_priority_handler));
7c673cae
FG
145
146 // Start an asynchronous accept that will complete immediately.
147 tcp::endpoint endpoint(boost::asio::ip::address_v4::loopback(), 0);
b32b8144
FG
148 tcp::acceptor acceptor(io_context, endpoint);
149 tcp::socket server_socket(io_context);
7c673cae
FG
150 acceptor.async_accept(server_socket,
151 pri_queue.wrap(100, high_priority_handler));
b32b8144 152 tcp::socket client_socket(io_context);
7c673cae
FG
153 client_socket.connect(acceptor.local_endpoint());
154
155 // Set a deadline timer to expire immediately.
b32b8144 156 boost::asio::deadline_timer timer(io_context);
7c673cae
FG
157 timer.expires_at(boost::posix_time::neg_infin);
158 timer.async_wait(pri_queue.wrap(42, middle_priority_handler));
159
b32b8144 160 while (io_context.run_one())
7c673cae
FG
161 {
162 // The custom invocation hook adds the handlers to the priority queue
163 // rather than executing them from within the poll_one() call.
b32b8144 164 while (io_context.poll_one())
7c673cae
FG
165 ;
166
167 pri_queue.execute_all();
168 }
169
170 return 0;
171}