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>