@@ -144,19 +144,53 @@ ssize_t Poll(struct pollfd* fds, int nfds, int timeout) noexcept {
144
144
#endif
145
145
}
146
146
147
+ #ifndef INVALID_SOCKET
148
+ const SOCKET INVALID_SOCKET = -1 ;
149
+ #endif
150
+
151
+ void CloseSocket (SOCKET socket) {
152
+ if (socket == INVALID_SOCKET)
153
+ return ;
154
+
155
+ #if defined(_win_)
156
+ closesocket (socket);
157
+ #else
158
+ close (socket);
159
+ #endif
160
+ }
161
+
162
+ struct SocketRAIIWrapper {
163
+ SOCKET socket = INVALID_SOCKET;
164
+
165
+ ~SocketRAIIWrapper () {
166
+ CloseSocket (socket);
167
+ }
168
+
169
+ SOCKET operator *() const {
170
+ return socket;
171
+ }
172
+
173
+ SOCKET release () {
174
+ auto result = socket;
175
+ socket = INVALID_SOCKET;
176
+
177
+ return result;
178
+ }
179
+ };
180
+
147
181
SOCKET SocketConnect (const NetworkAddress& addr, const SocketTimeoutParams& timeout_params) {
148
182
int last_err = 0 ;
149
183
for (auto res = addr.Info (); res != nullptr ; res = res->ai_next ) {
150
- SOCKET s ( socket (res->ai_family , res->ai_socktype , res->ai_protocol )) ;
184
+ SocketRAIIWrapper s{ socket (res->ai_family , res->ai_socktype , res->ai_protocol )} ;
151
185
152
- if (s == - 1 ) {
186
+ if (* s == INVALID_SOCKET ) {
153
187
continue ;
154
188
}
155
189
156
- SetNonBlock (s, true );
157
- SetTimeout (s, timeout_params);
190
+ SetNonBlock (* s, true );
191
+ SetTimeout (* s, timeout_params);
158
192
159
- if (connect (s, res->ai_addr , (int )res->ai_addrlen ) != 0 ) {
193
+ if (connect (* s, res->ai_addr , (int )res->ai_addrlen ) != 0 ) {
160
194
int err = getSocketErrorCode ();
161
195
if (
162
196
err == EINPROGRESS || err == EAGAIN || err == EWOULDBLOCK
@@ -165,7 +199,7 @@ SOCKET SocketConnect(const NetworkAddress& addr, const SocketTimeoutParams& time
165
199
#endif
166
200
) {
167
201
pollfd fd;
168
- fd.fd = s;
202
+ fd.fd = * s;
169
203
fd.events = POLLOUT;
170
204
fd.revents = 0 ;
171
205
ssize_t rval = Poll (&fd, 1 , 5000 );
@@ -175,18 +209,18 @@ SOCKET SocketConnect(const NetworkAddress& addr, const SocketTimeoutParams& time
175
209
}
176
210
if (rval > 0 ) {
177
211
socklen_t len = sizeof (err);
178
- getsockopt (s, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
212
+ getsockopt (* s, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
179
213
180
214
if (!err) {
181
- SetNonBlock (s, false );
182
- return s;
215
+ SetNonBlock (* s, false );
216
+ return s. release () ;
183
217
}
184
218
last_err = err;
185
219
}
186
220
}
187
221
} else {
188
- SetNonBlock (s, false );
189
- return s;
222
+ SetNonBlock (* s, false );
223
+ return s. release () ;
190
224
}
191
225
}
192
226
if (last_err > 0 ) {
@@ -265,15 +299,15 @@ Socket::Socket(const NetworkAddress & addr)
265
299
Socket::Socket (Socket&& other) noexcept
266
300
: handle_(other.handle_)
267
301
{
268
- other.handle_ = - 1 ;
302
+ other.handle_ = INVALID_SOCKET ;
269
303
}
270
304
271
305
Socket& Socket::operator =(Socket&& other) noexcept {
272
306
if (this != &other) {
273
307
Close ();
274
308
275
309
handle_ = other.handle_ ;
276
- other.handle_ = - 1 ;
310
+ other.handle_ = INVALID_SOCKET ;
277
311
}
278
312
279
313
return *this ;
@@ -284,14 +318,8 @@ Socket::~Socket() {
284
318
}
285
319
286
320
void Socket::Close () {
287
- if (handle_ != -1 ) {
288
- #if defined(_win_)
289
- closesocket (handle_);
290
- #else
291
- close (handle_);
292
- #endif
293
- handle_ = -1 ;
294
- }
321
+ CloseSocket (handle_);
322
+ handle_ = INVALID_SOCKET;
295
323
}
296
324
297
325
void Socket::SetTcpKeepAlive (int idle, int intvl, int cnt) noexcept {
0 commit comments