summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorJan Dubois <jand@activestate.com>2009-10-13 16:46:58 -0700
committerJan Dubois <jand@activestate.com>2009-10-13 16:46:58 -0700
commite4d771f5006ebd70b76422437cce60e9ac40c830 (patch)
tree29862aebef69b67e2c77dc7ffd5a38ddcfd70efa /win32
parent50e225a377de7c314b13cbaf39b6b423215d84a7 (diff)
downloadperl-e4d771f5006ebd70b76422437cce60e9ac40c830.tar.gz
The winsock select() implementation doesn't support all empty 'fd_set's.
The code already contained a workaround for the special case select(undef, undef, undef, $sleep); but didn't handle the case when actual bit vectors were passed in that didn't have any bits set. Fixes http://rt.perl.org/rt3/Public/Bug/Display.html?id=54544
Diffstat (limited to 'win32')
-rw-r--r--win32/win32sck.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/win32/win32sck.c b/win32/win32sck.c
index 8ff0196d1c..dd46bb3a64 100644
--- a/win32/win32sck.c
+++ b/win32/win32sck.c
@@ -261,18 +261,8 @@ win32_select(int nfds, Perl_fd_set* rd, Perl_fd_set* wr, Perl_fd_set* ex, const
#ifdef USE_SOCKETS_AS_HANDLES
int i, fd, save_errno = errno;
FD_SET nrd, nwr, nex;
+ bool just_sleep = TRUE;
- /* winsock seems incapable of dealing with all three null fd_sets,
- * so do the (millisecond) sleep as a special case
- */
- if (!(rd || wr || ex)) {
- if (timeout)
- Sleep(timeout->tv_sec * 1000 +
- timeout->tv_usec / 1000); /* do the best we can */
- else
- Sleep(UINT_MAX);
- return 0;
- }
StartSockets();
FD_ZERO(&nrd);
@@ -282,17 +272,32 @@ win32_select(int nfds, Perl_fd_set* rd, Perl_fd_set* wr, Perl_fd_set* ex, const
if (rd && PERL_FD_ISSET(i,rd)) {
fd = TO_SOCKET(i);
FD_SET((unsigned)fd, &nrd);
+ just_sleep = FALSE;
}
if (wr && PERL_FD_ISSET(i,wr)) {
fd = TO_SOCKET(i);
FD_SET((unsigned)fd, &nwr);
+ just_sleep = FALSE;
}
if (ex && PERL_FD_ISSET(i,ex)) {
fd = TO_SOCKET(i);
FD_SET((unsigned)fd, &nex);
+ just_sleep = FALSE;
}
}
+ /* winsock seems incapable of dealing with all three fd_sets being empty,
+ * so do the (millisecond) sleep as a special case
+ */
+ if (just_sleep) {
+ if (timeout)
+ Sleep(timeout->tv_sec * 1000 +
+ timeout->tv_usec / 1000); /* do the best we can */
+ else
+ Sleep(UINT_MAX);
+ return 0;
+ }
+
errno = save_errno;
SOCKET_TEST_ERROR(r = select(nfds, &nrd, &nwr, &nex, timeout));
save_errno = errno;