Mercurial > code
comparison C++/SocketListener.h @ 270:46ccfbee84d9
Socket:
* Add macro SOCKET_LISTENER_HAVE_POLL to enable / disable poll(2) method
if it is not available. Fallback safely to select(2) if needed.
* Add new function selectMultiple() which returns a std::vector of all ready
sockets.
* Add tests for multiple selection.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 21 Oct 2014 10:13:33 +0200 |
parents | 4ad3c85ab73e |
children | f7000cc599d0 |
comparison
equal
deleted
inserted
replaced
269:44dcc198bf0c | 270:46ccfbee84d9 |
---|---|
19 #ifndef _SOCKET_LISTENER_H_ | 19 #ifndef _SOCKET_LISTENER_H_ |
20 #define _SOCKET_LISTENER_H_ | 20 #define _SOCKET_LISTENER_H_ |
21 | 21 |
22 #include <chrono> | 22 #include <chrono> |
23 #include <functional> | 23 #include <functional> |
24 #include <vector> | |
24 | 25 |
25 #include "Socket.h" | 26 #include "Socket.h" |
27 | |
28 #if defined(_WIN32) | |
29 # if _WIN32_WINNT >= 0x0600 | |
30 # define SOCKET_LISTENER_HAVE_POLL | |
31 # endif | |
32 #else | |
33 # define SOCKET_LISTENER_HAVE_POLL | |
34 #endif | |
26 | 35 |
27 /** | 36 /** |
28 * @enum SocketDirection | 37 * @enum SocketDirection |
29 * @brief The SocketDirection enum | 38 * @brief The SocketDirection enum |
30 * | 39 * |
111 /** | 120 /** |
112 * @brief Function for listing all sockets | 121 * @brief Function for listing all sockets |
113 */ | 122 */ |
114 using MapFunc = std::function<void (Socket &, SocketDirection)>; | 123 using MapFunc = std::function<void (Socket &, SocketDirection)>; |
115 | 124 |
125 #if defined(SOCKET_LISTENER_HAVE_POLL) | |
126 static constexpr const SocketMethod PreferredMethod = SocketMethod::Poll; | |
127 #else | |
128 static constexpr const SocketMethod PreferredMethod = SocketMethod::Select; | |
129 #endif | |
130 | |
116 /** | 131 /** |
117 * @class Interface | 132 * @class Interface |
118 * @brief Implement the polling method | 133 * @brief Implement the polling method |
119 */ | 134 */ |
120 class Interface { | 135 class Interface { |
156 * Get the total number of sockets in the listener. | 171 * Get the total number of sockets in the listener. |
157 */ | 172 */ |
158 virtual unsigned size() const = 0; | 173 virtual unsigned size() const = 0; |
159 | 174 |
160 /** | 175 /** |
161 * Select a socket. | 176 * Select one socket. |
162 * | 177 * |
163 * @param ms the number of milliseconds to wait, -1 means forever | 178 * @param ms the number of milliseconds to wait, -1 means forever |
164 * @return the socket status | 179 * @return the socket status |
165 * @throw error::Failure on failure | 180 * @throw error::Failure on failure |
166 * @throw error::Timeout on timeout | 181 * @throw error::Timeout on timeout |
167 */ | 182 */ |
168 virtual SocketStatus select(int ms) = 0; | 183 virtual SocketStatus select(int ms) = 0; |
184 | |
185 /** | |
186 * Select many sockets. | |
187 * | |
188 * @param ms the number of milliseconds to wait, -1 means forever | |
189 * @return a vector of ready sockets | |
190 * @throw error::Failure on failure | |
191 * @throw error::Timeout on timeout | |
192 */ | |
193 virtual std::vector<SocketStatus> selectMultiple(int ms) = 0; | |
169 }; | 194 }; |
170 | 195 |
171 std::unique_ptr<Interface> m_interface; | 196 std::unique_ptr<Interface> m_interface; |
172 | |
173 #if defined(_WIN32) | |
174 # if _WIN32_WINNT >= 0x0600 | |
175 static constexpr const SocketMethod PreferredMethod = SocketMethod::Poll; | |
176 # else | |
177 static constexpr const SocketMethod PreferredMethod = SocketMethod::Select; | |
178 # endif | |
179 #else | |
180 static constexpr const SocketMethod PreferredMethod = SocketMethod::Poll; | |
181 #endif | |
182 | 197 |
183 public: | 198 public: |
184 /** | 199 /** |
185 * Create a socket listener. | 200 * Create a socket listener. |
186 * | 201 * |
229 } | 244 } |
230 | 245 |
231 /** | 246 /** |
232 * Select a socket. Waits for a specific amount of time specified as the duration. | 247 * Select a socket. Waits for a specific amount of time specified as the duration. |
233 * | 248 * |
249 * @param duration the duration | |
234 * @return the socket ready | 250 * @return the socket ready |
235 * @throw SocketError on error | 251 * @throw SocketError on error |
236 * @throw SocketTimeout on timeout | 252 * @throw SocketTimeout on timeout |
237 */ | 253 */ |
238 template <typename Rep, typename Ratio> | 254 template <typename Rep, typename Ratio> |
254 { | 270 { |
255 return m_interface->select(-1); | 271 return m_interface->select(-1); |
256 } | 272 } |
257 | 273 |
258 /** | 274 /** |
275 * Select multiple sockets. | |
276 * | |
277 * @param duration the duration | |
278 * @return the socket ready | |
279 * @throw SocketError on error | |
280 * @throw SocketTimeout on timeout | |
281 */ | |
282 template <typename Rep, typename Ratio> | |
283 inline std::vector<SocketStatus> selectMultiple(const std::chrono::duration<Rep, Ratio> &duration) | |
284 { | |
285 auto cvt = std::chrono::duration_cast<std::chrono::milliseconds>(duration); | |
286 | |
287 return m_interface->selectMultiple(cvt.count()); | |
288 } | |
289 | |
290 /** | |
291 * Overload that waits indefinitely. | |
292 * | |
293 * @return the socket ready | |
294 * @throw SocketError on error | |
295 * @throw SocketTimeout on timeout | |
296 */ | |
297 inline std::vector<SocketStatus> selectMultiple() | |
298 { | |
299 return m_interface->selectMultiple(-1); | |
300 } | |
301 | |
302 /** | |
259 * List every socket in the listener. | 303 * List every socket in the listener. |
260 * | 304 * |
261 * @param func the function to call | 305 * @param func the function to call |
262 */ | 306 */ |
263 template <typename Func> | 307 template <typename Func> |