]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // detail/reactor_op_queue.hpp | |
3 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
4 | // | |
11fdf7f2 | 5 | // Copyright (c) 2003-2018 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 | #ifndef BOOST_ASIO_DETAIL_REACTOR_OP_QUEUE_HPP | |
12 | #define BOOST_ASIO_DETAIL_REACTOR_OP_QUEUE_HPP | |
13 | ||
14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) | |
15 | # pragma once | |
16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) | |
17 | ||
18 | #include <boost/asio/detail/config.hpp> | |
19 | #include <boost/asio/detail/hash_map.hpp> | |
20 | #include <boost/asio/detail/noncopyable.hpp> | |
21 | #include <boost/asio/detail/op_queue.hpp> | |
22 | #include <boost/asio/detail/reactor_op.hpp> | |
23 | #include <boost/asio/error.hpp> | |
24 | ||
25 | #include <boost/asio/detail/push_options.hpp> | |
26 | ||
27 | namespace boost { | |
28 | namespace asio { | |
29 | namespace detail { | |
30 | ||
31 | template <typename Descriptor> | |
32 | class reactor_op_queue | |
33 | : private noncopyable | |
34 | { | |
35 | public: | |
36 | typedef Descriptor key_type; | |
37 | ||
38 | struct mapped_type : op_queue<reactor_op> | |
39 | { | |
40 | mapped_type() {} | |
41 | mapped_type(const mapped_type&) {} | |
42 | void operator=(const mapped_type&) {} | |
43 | }; | |
44 | ||
45 | typedef typename hash_map<key_type, mapped_type>::value_type value_type; | |
46 | typedef typename hash_map<key_type, mapped_type>::iterator iterator; | |
47 | ||
48 | // Constructor. | |
49 | reactor_op_queue() | |
50 | : operations_() | |
51 | { | |
52 | } | |
53 | ||
54 | // Obtain iterators to all registered descriptors. | |
55 | iterator begin() { return operations_.begin(); } | |
56 | iterator end() { return operations_.end(); } | |
57 | ||
58 | // Add a new operation to the queue. Returns true if this is the only | |
59 | // operation for the given descriptor, in which case the reactor's event | |
60 | // demultiplexing function call may need to be interrupted and restarted. | |
61 | bool enqueue_operation(Descriptor descriptor, reactor_op* op) | |
62 | { | |
63 | std::pair<iterator, bool> entry = | |
64 | operations_.insert(value_type(descriptor, mapped_type())); | |
65 | entry.first->second.push(op); | |
66 | return entry.second; | |
67 | } | |
68 | ||
69 | // Cancel all operations associated with the descriptor identified by the | |
70 | // supplied iterator. Any operations pending for the descriptor will be | |
71 | // cancelled. Returns true if any operations were cancelled, in which case | |
72 | // the reactor's event demultiplexing function may need to be interrupted and | |
73 | // restarted. | |
74 | bool cancel_operations(iterator i, op_queue<operation>& ops, | |
75 | const boost::system::error_code& ec = | |
76 | boost::asio::error::operation_aborted) | |
77 | { | |
78 | if (i != operations_.end()) | |
79 | { | |
80 | while (reactor_op* op = i->second.front()) | |
81 | { | |
82 | op->ec_ = ec; | |
83 | i->second.pop(); | |
84 | ops.push(op); | |
85 | } | |
86 | operations_.erase(i); | |
87 | return true; | |
88 | } | |
89 | ||
90 | return false; | |
91 | } | |
92 | ||
93 | // Cancel all operations associated with the descriptor. Any operations | |
94 | // pending for the descriptor will be cancelled. Returns true if any | |
95 | // operations were cancelled, in which case the reactor's event | |
96 | // demultiplexing function may need to be interrupted and restarted. | |
97 | bool cancel_operations(Descriptor descriptor, op_queue<operation>& ops, | |
98 | const boost::system::error_code& ec = | |
99 | boost::asio::error::operation_aborted) | |
100 | { | |
101 | return this->cancel_operations(operations_.find(descriptor), ops, ec); | |
102 | } | |
103 | ||
104 | // Whether there are no operations in the queue. | |
105 | bool empty() const | |
106 | { | |
107 | return operations_.empty(); | |
108 | } | |
109 | ||
110 | // Determine whether there are any operations associated with the descriptor. | |
111 | bool has_operation(Descriptor descriptor) const | |
112 | { | |
113 | return operations_.find(descriptor) != operations_.end(); | |
114 | } | |
115 | ||
116 | // Perform the operations corresponding to the descriptor identified by the | |
117 | // supplied iterator. Returns true if there are still unfinished operations | |
118 | // queued for the descriptor. | |
119 | bool perform_operations(iterator i, op_queue<operation>& ops) | |
120 | { | |
121 | if (i != operations_.end()) | |
122 | { | |
123 | while (reactor_op* op = i->second.front()) | |
124 | { | |
125 | if (op->perform()) | |
126 | { | |
127 | i->second.pop(); | |
128 | ops.push(op); | |
129 | } | |
130 | else | |
131 | { | |
132 | return true; | |
133 | } | |
134 | } | |
135 | operations_.erase(i); | |
136 | } | |
137 | return false; | |
138 | } | |
139 | ||
140 | // Perform the operations corresponding to the descriptor. Returns true if | |
141 | // there are still unfinished operations queued for the descriptor. | |
142 | bool perform_operations(Descriptor descriptor, op_queue<operation>& ops) | |
143 | { | |
144 | return this->perform_operations(operations_.find(descriptor), ops); | |
145 | } | |
146 | ||
147 | // Get all operations owned by the queue. | |
148 | void get_all_operations(op_queue<operation>& ops) | |
149 | { | |
150 | iterator i = operations_.begin(); | |
151 | while (i != operations_.end()) | |
152 | { | |
153 | iterator op_iter = i++; | |
154 | ops.push(op_iter->second); | |
155 | operations_.erase(op_iter); | |
156 | } | |
157 | } | |
158 | ||
159 | private: | |
160 | // The operations that are currently executing asynchronously. | |
161 | hash_map<key_type, mapped_type> operations_; | |
162 | }; | |
163 | ||
164 | } // namespace detail | |
165 | } // namespace asio | |
166 | } // namespace boost | |
167 | ||
168 | #include <boost/asio/detail/pop_options.hpp> | |
169 | ||
170 | #endif // BOOST_ASIO_DETAIL_REACTOR_OP_QUEUE_HPP |