Realistic 3D camera system
3D camera system components
epoll_reactor.hpp
Go to the documentation of this file.
1 //
2 // detail/epoll_reactor.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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 ASIO_DETAIL_EPOLL_REACTOR_HPP
12 #define ASIO_DETAIL_EPOLL_REACTOR_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include "asio/detail/config.hpp"
19 
20 #if defined(ASIO_HAS_EPOLL)
21 
22 #include "asio/io_service.hpp"
24 #include "asio/detail/limits.hpp"
25 #include "asio/detail/mutex.hpp"
27 #include "asio/detail/op_queue.hpp"
33 #include "asio/detail/wait_op.hpp"
34 
36 
37 namespace asio {
38 namespace detail {
39 
40 class epoll_reactor
41  : public asio::detail::service_base<epoll_reactor>
42 {
43 public:
44  enum op_types { read_op = 0, write_op = 1,
45  connect_op = 1, except_op = 2, max_ops = 3 };
46 
47  // Per-descriptor queues.
48  class descriptor_state : operation
49  {
50  friend class epoll_reactor;
51  friend class object_pool_access;
52 
53  descriptor_state* next_;
54  descriptor_state* prev_;
55 
56  mutex mutex_;
57  epoll_reactor* reactor_;
58  int descriptor_;
59  uint32_t registered_events_;
60  op_queue<reactor_op> op_queue_[max_ops];
61  bool shutdown_;
62 
63  ASIO_DECL descriptor_state();
64  void set_ready_events(uint32_t events) { task_result_ = events; }
65  ASIO_DECL operation* perform_io(uint32_t events);
66  ASIO_DECL static void do_complete(
67  io_service_impl* owner, operation* base,
68  const asio::error_code& ec, std::size_t bytes_transferred);
69  };
70 
71  // Per-descriptor data.
72  typedef descriptor_state* per_descriptor_data;
73 
74  // Constructor.
75  ASIO_DECL epoll_reactor(asio::io_service& io_service);
76 
77  // Destructor.
78  ASIO_DECL ~epoll_reactor();
79 
80  // Destroy all user-defined handler objects owned by the service.
81  ASIO_DECL void shutdown_service();
82 
83  // Recreate internal descriptors following a fork.
84  ASIO_DECL void fork_service(
86 
87  // Initialise the task.
88  ASIO_DECL void init_task();
89 
90  // Register a socket with the reactor. Returns 0 on success, system error
91  // code on failure.
92  ASIO_DECL int register_descriptor(socket_type descriptor,
93  per_descriptor_data& descriptor_data);
94 
95  // Register a descriptor with an associated single operation. Returns 0 on
96  // success, system error code on failure.
97  ASIO_DECL int register_internal_descriptor(
98  int op_type, socket_type descriptor,
99  per_descriptor_data& descriptor_data, reactor_op* op);
100 
101  // Move descriptor registration from one descriptor_data object to another.
102  ASIO_DECL void move_descriptor(socket_type descriptor,
103  per_descriptor_data& target_descriptor_data,
104  per_descriptor_data& source_descriptor_data);
105 
106  // Post a reactor operation for immediate completion.
107  void post_immediate_completion(reactor_op* op, bool is_continuation)
108  {
109  io_service_.post_immediate_completion(op, is_continuation);
110  }
111 
112  // Start a new operation. The reactor operation will be performed when the
113  // given descriptor is flagged as ready, or an error has occurred.
114  ASIO_DECL void start_op(int op_type, socket_type descriptor,
115  per_descriptor_data& descriptor_data, reactor_op* op,
116  bool is_continuation, bool allow_speculative);
117 
118  // Cancel all operations associated with the given descriptor. The
119  // handlers associated with the descriptor will be invoked with the
120  // operation_aborted error.
121  ASIO_DECL void cancel_ops(socket_type descriptor,
122  per_descriptor_data& descriptor_data);
123 
124  // Cancel any operations that are running against the descriptor and remove
125  // its registration from the reactor.
126  ASIO_DECL void deregister_descriptor(socket_type descriptor,
127  per_descriptor_data& descriptor_data, bool closing);
128 
129  // Remote the descriptor's registration from the reactor.
130  ASIO_DECL void deregister_internal_descriptor(
131  socket_type descriptor, per_descriptor_data& descriptor_data);
132 
133  // Add a new timer queue to the reactor.
134  template <typename Time_Traits>
135  void add_timer_queue(timer_queue<Time_Traits>& timer_queue);
136 
137  // Remove a timer queue from the reactor.
138  template <typename Time_Traits>
139  void remove_timer_queue(timer_queue<Time_Traits>& timer_queue);
140 
141  // Schedule a new operation in the given timer queue to expire at the
142  // specified absolute time.
143  template <typename Time_Traits>
144  void schedule_timer(timer_queue<Time_Traits>& queue,
145  const typename Time_Traits::time_type& time,
146  typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op);
147 
148  // Cancel the timer operations associated with the given token. Returns the
149  // number of operations that have been posted or dispatched.
150  template <typename Time_Traits>
151  std::size_t cancel_timer(timer_queue<Time_Traits>& queue,
152  typename timer_queue<Time_Traits>::per_timer_data& timer,
153  std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());
154 
155  // Run epoll once until interrupted or events are ready to be dispatched.
156  ASIO_DECL void run(bool block, op_queue<operation>& ops);
157 
158  // Interrupt the select loop.
159  ASIO_DECL void interrupt();
160 
161 private:
162  // The hint to pass to epoll_create to size its data structures.
163  enum { epoll_size = 20000 };
164 
165  // Create the epoll file descriptor. Throws an exception if the descriptor
166  // cannot be created.
167  ASIO_DECL static int do_epoll_create();
168 
169  // Create the timerfd file descriptor. Does not throw.
170  ASIO_DECL static int do_timerfd_create();
171 
172  // Allocate a new descriptor state object.
173  ASIO_DECL descriptor_state* allocate_descriptor_state();
174 
175  // Free an existing descriptor state object.
176  ASIO_DECL void free_descriptor_state(descriptor_state* s);
177 
178  // Helper function to add a new timer queue.
179  ASIO_DECL void do_add_timer_queue(timer_queue_base& queue);
180 
181  // Helper function to remove a timer queue.
182  ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue);
183 
184  // Called to recalculate and update the timeout.
185  ASIO_DECL void update_timeout();
186 
187  // Get the timeout value for the epoll_wait call. The timeout value is
188  // returned as a number of milliseconds. A return value of -1 indicates
189  // that epoll_wait should block indefinitely.
190  ASIO_DECL int get_timeout();
191 
192 #if defined(ASIO_HAS_TIMERFD)
193  // Get the timeout value for the timer descriptor. The return value is the
194  // flag argument to be used when calling timerfd_settime.
195  ASIO_DECL int get_timeout(itimerspec& ts);
196 #endif // defined(ASIO_HAS_TIMERFD)
197 
198  // The io_service implementation used to post completions.
199  io_service_impl& io_service_;
200 
201  // Mutex to protect access to internal data.
202  mutex mutex_;
203 
204  // The interrupter is used to break a blocking epoll_wait call.
205  select_interrupter interrupter_;
206 
207  // The epoll file descriptor.
208  int epoll_fd_;
209 
210  // The timer file descriptor.
211  int timer_fd_;
212 
213  // The timer queues.
214  timer_queue_set timer_queues_;
215 
216  // Whether the service has been shut down.
217  bool shutdown_;
218 
219  // Mutex to protect access to the registered descriptors.
220  mutex registered_descriptors_mutex_;
221 
222  // Keep track of all registered descriptors.
223  object_pool<descriptor_state> registered_descriptors_;
224 
225  // Helper class to do post-perform_io cleanup.
226  struct perform_io_cleanup_on_block_exit;
227  friend struct perform_io_cleanup_on_block_exit;
228 };
229 
230 } // namespace detail
231 } // namespace asio
232 
234 
236 #if defined(ASIO_HEADER_ONLY)
238 #endif // defined(ASIO_HEADER_ONLY)
239 
240 #endif // defined(ASIO_HAS_EPOLL)
241 
242 #endif // ASIO_DETAIL_EPOLL_REACTOR_HPP
Provides core I/O functionality.
Definition: io_service.hpp:184
SocketService & s
Definition: connect.hpp:521
null_mutex mutex
Definition: mutex.hpp:36
class task_io_service io_service_impl
Definition: io_service.hpp:48
pipe_select_interrupter select_interrupter
fork_event
Fork-related event notifications.
Definition: io_service.hpp:501
bool is_continuation(Context &context)
Class to represent an error code value.
Definition: error_code.hpp:80
#define ASIO_DECL
Definition: config.hpp:43
task_io_service_operation operation
Definition: operation.hpp:32