Skip to content

Commit e5648cc

Browse files
committed
socket-win32.cxx (acceptSocket): Change implementation to use select() to allow timeouts.
2 parents d2ed8e8 + 3ddb01d commit e5648cc

File tree

1 file changed

+61
-4
lines changed

1 file changed

+61
-4
lines changed

src/socket-win32.cxx

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <log4cplus/internal/socket.h>
2929
#include <log4cplus/helpers/loglog.h>
3030
#include <log4cplus/thread/threads.h>
31+
#include <log4cplus/helpers/stringhelper.h>
3132

3233

3334
/////////////////////////////////////////////////////////////////////////////
@@ -261,12 +262,68 @@ acceptSocket(SOCKET_TYPE sock, SocketState & state)
261262
{
262263
init_winsock ();
263264

264-
SOCKET connected_socket = ::accept (to_os_socket (sock), NULL, NULL);
265+
SOCKET osSocket = to_os_socket (sock);
265266

266-
if (connected_socket != INVALID_OS_SOCKET_VALUE)
267-
state = ok;
267+
// Check that the socket is ok.
268268

269-
return to_log4cplus_socket (connected_socket);
269+
int val = 0;
270+
int optlen = sizeof (val);
271+
int ret = getsockopt (osSocket, SOL_SOCKET, SO_TYPE,
272+
reinterpret_cast<char *>(&val), &optlen);
273+
if (ret == SOCKET_ERROR)
274+
goto error;
275+
276+
// Now that we know the socket is working ok we can wait for
277+
// either a new connection or for a transition to bad state.
278+
279+
while (1)
280+
{
281+
fd_set readSet;
282+
timeval timeout;
283+
284+
FD_ZERO (&readSet);
285+
FD_SET (osSocket, &readSet);
286+
timeout.tv_sec = 0;
287+
timeout.tv_usec = 200 * 1000;
288+
289+
int selectResponse = ::select (1, &readSet, NULL, NULL, &timeout);
290+
if (selectResponse < 0)
291+
{
292+
DWORD const eno = WSAGetLastError ();
293+
if (eno == WSAENOTSOCK || eno == WSAEINVAL)
294+
WSASetLastError (ERROR_NO_DATA);
295+
296+
goto error;
297+
}
298+
else if (selectResponse == 0)
299+
// Timeout.
300+
continue;
301+
else if (selectResponse == 1)
302+
{
303+
SOCKET connected_socket = ::accept (osSocket, NULL, NULL);
304+
305+
if (connected_socket != INVALID_OS_SOCKET_VALUE)
306+
state = ok;
307+
else
308+
goto error;
309+
310+
return to_log4cplus_socket (connected_socket);
311+
}
312+
else
313+
{
314+
helpers::getLogLog ().error (
315+
LOG4CPLUS_TEXT ("unexpected select() return value: ")
316+
+ helpers::convertIntegerToString (selectResponse));
317+
WSASetLastError (ERROR_UNSUPPORTED_TYPE);
318+
goto error;
319+
}
320+
}
321+
322+
error:
323+
DWORD eno = WSAGetLastError ();
324+
set_last_socket_error (eno);
325+
326+
return to_log4cplus_socket (INVALID_SOCKET);
270327
}
271328

272329

0 commit comments

Comments
 (0)