In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/e4d771f5006ebd70b76422437cce60e9ac40c830?hp=50e225a377de7c314b13cbaf39b6b423215d84a7>
- Log ----------------------------------------------------------------- commit e4d771f5006ebd70b76422437cce60e9ac40c830 Author: Jan Dubois <[email protected]> Date: Tue Oct 13 16:46:58 2009 -0700 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 ----------------------------------------------------------------------- Summary of changes: t/op/sselect.t | 13 ++++++++++++- win32/win32sck.c | 27 ++++++++++++++++----------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/t/op/sselect.t b/t/op/sselect.t index 0f877b1..332b7c0 100644 --- a/t/op/sselect.t +++ b/t/op/sselect.t @@ -7,7 +7,7 @@ BEGIN { require 'test.pl'; -plan (9); +plan (11); my $blank = ""; eval {select undef, $blank, $blank, 0}; @@ -30,3 +30,14 @@ eval {select $blank, "a", $blank, 0}; like ($@, qr/^Modification of a read-only value attempted/); eval {select $blank, $blank, "a", 0}; like ($@, qr/^Modification of a read-only value attempted/); + +my $sleep = 3; +my $t = time; +select(undef, undef, undef, $sleep); +ok(time-$t >= $sleep, "$sleep seconds have passed"); + +my $empty = ""; +vec($empty,0,1) = 0; +$t = time; +select($empty, undef, undef, $sleep); +ok(time-$t >= $sleep, "$sleep seconds have passed"); diff --git a/win32/win32sck.c b/win32/win32sck.c index 8ff0196..dd46bb3 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; -- Perl5 Master Repository
