diff options
author | Jan Dubois <jand@activestate.com> | 2009-10-13 16:46:58 -0700 |
---|---|---|
committer | Jan Dubois <jand@activestate.com> | 2009-10-13 16:46:58 -0700 |
commit | e4d771f5006ebd70b76422437cce60e9ac40c830 (patch) | |
tree | 29862aebef69b67e2c77dc7ffd5a38ddcfd70efa /win32/win32sck.c | |
parent | 50e225a377de7c314b13cbaf39b6b423215d84a7 (diff) | |
download | perl-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/win32sck.c')
-rw-r--r-- | win32/win32sck.c | 27 |
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; |