Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PATCH] Fix IO::Poll handling of empty fd array #14989

Closed
p5pRT opened this issue Oct 16, 2015 · 7 comments
Closed

[PATCH] Fix IO::Poll handling of empty fd array #14989

p5pRT opened this issue Oct 16, 2015 · 7 comments

Comments

@p5pRT
Copy link

p5pRT commented Oct 16, 2015

Migrated from rt.perl.org#126374 (status was 'resolved')

Searchable as RT126374$

@p5pRT
Copy link
Author

p5pRT commented Oct 16, 2015

From @ilmari

Here are two patches which together fix IO​::Poll's handling of empty
poll arrays, both in the perl and XS parts.

@p5pRT
Copy link
Author

p5pRT commented Oct 16, 2015

From @ilmari

0001-Fix-assertion-when-calling-IO-Poll-_poll-with-an-emp.patch
From 1a3e2ef16d3d6915a126a3fbb3eb527f3b9d8a3f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= <ilmari@ilmari.org>
Date: Fri, 16 Oct 2015 17:20:04 +0100
Subject: [PATCH 1/2] Fix assertion when calling IO::Poll::_poll() with an
 empty fd array
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

  perl: IO.xs:322: XS_IO__Poll__poll: Assertion
  `PL_valid_types_PVX[((svtype)((_svpvx)->sv_flags & 0xff)) & 0xf]'
  failed.

This is because NEWSV(…, 0) returns undef, with a grabage pointer in
the PV slot.  This doesn't seem to matter in practice, since nothing
actually dereferences the pointer when nfds is zero, but to be safe we
should pass in _some_ valid pointer, so just use the SV* itself;
---
 dist/IO/IO.pm | 2 +-
 dist/IO/IO.xs | 5 ++++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/dist/IO/IO.pm b/dist/IO/IO.pm
index 2762958..de3e991 100644
--- a/dist/IO/IO.pm
+++ b/dist/IO/IO.pm
@@ -7,7 +7,7 @@ package IO;
 use strict;
 use warnings;
 
-our $VERSION = "1.35";
+our $VERSION = "1.36";
 XSLoader::load 'IO', $VERSION;
 
 sub import {
diff --git a/dist/IO/IO.xs b/dist/IO/IO.xs
index 1f546b9..fe749a6 100644
--- a/dist/IO/IO.xs
+++ b/dist/IO/IO.xs
@@ -319,7 +319,10 @@ _poll(timeout,...)
 #ifdef HAS_POLL
     const int nfd = (items - 1) / 2;
     SV *tmpsv = NEWSV(999,nfd * sizeof(struct pollfd));
-    struct pollfd *fds = (struct pollfd *)SvPVX(tmpsv);
+    /* We should pass _some_ valid pointer even if nfd is zero, but it
+     * doesn't matter what it is, since we're telling it to not check any fds.
+     */
+    struct pollfd *fds = nfd ? (struct pollfd *)SvPVX(tmpsv) : (struct pollfd *)tmpsv;
     int i,j,ret;
     for(i=1, j=0  ; j < nfd ; j++) {
 	fds[j].fd = SvIV(ST(i));
-- 
2.6.1

@p5pRT
Copy link
Author

p5pRT commented Oct 16, 2015

From @ilmari

0002-Make-IO-Poll-poll-call-_poll-even-with-an-empty-fd-a.patch
From 8255ee3a96bbc4b3f237eecabefa546c82b8520d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= <ilmari@ilmari.org>
Date: Fri, 16 Oct 2015 17:23:40 +0100
Subject: [PATCH 2/2] Make IO::Poll->poll call _poll even with an empty fd
 array

Now that _poll() properly handles an empty array, this fixes
[rt.cpan.org #25049].  The commit referenced in that ticket never made
it to CPAN nor blead.
---
 dist/IO/lib/IO/Poll.pm |  4 ++--
 dist/IO/t/io_poll.t    | 11 ++++++++++-
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/dist/IO/lib/IO/Poll.pm b/dist/IO/lib/IO/Poll.pm
index 47f1a13..a02dc3d 100644
--- a/dist/IO/lib/IO/Poll.pm
+++ b/dist/IO/lib/IO/Poll.pm
@@ -13,7 +13,7 @@ package IO::Poll;
 our(@ISA, @EXPORT_OK, @EXPORT, $VERSION);
 
 @ISA = qw(Exporter);
-$VERSION = "0.09";
+$VERSION = "0.10";
 
 @EXPORT = qw( POLLIN
 	      POLLOUT
@@ -83,7 +83,7 @@ sub poll {
 	push(@poll,$fd => $mask);
     }
 
-    my $ret = @poll ? _poll(defined($timeout) ? $timeout * 1000 : -1,@poll) : 0;
+    my $ret = _poll(defined($timeout) ? $timeout * 1000 : -1,@poll);
 
     return $ret
 	unless $ret > 0;
diff --git a/dist/IO/t/io_poll.t b/dist/IO/t/io_poll.t
index 364d346..c58467c 100644
--- a/dist/IO/t/io_poll.t
+++ b/dist/IO/t/io_poll.t
@@ -8,7 +8,7 @@
 select(STDERR); $| = 1;
 select(STDOUT); $| = 1;
 
-print "1..10\n";
+print "1..12\n";
 
 use IO::Handle;
 use IO::Poll qw(/POLL/);
@@ -81,3 +81,12 @@
 print "not "
     if $poll->poll(0.1);
 print "ok 10\n";
+
+my $wait = IO::Poll->new;
+my $now = time;
+my $zero = $wait->poll(2);
+my $diff = time - $now;
+print "not " if !defined($zero) or $zero;
+print "ok 11\n";
+print "not " unless $diff >= 2;
+print "ok 12\n";
-- 
2.6.1

@p5pRT
Copy link
Author

p5pRT commented Oct 16, 2015

From @ilmari

--
"I use RMS as a guide in the same way that a boat captain would use
a lighthouse. It's good to know where it is, but you generally
don't want to find yourself in the same spot." - Tollef Fog Heen

@p5pRT
Copy link
Author

p5pRT commented Oct 19, 2015

From @tonycoz

On Fri Oct 16 09​:55​:54 2015, ilmari wrote​:

Here are two patches which together fix IO​::Poll's handling of empty
poll arrays, both in the perl and XS parts.

Thanks, applied as 908febd and 03a8022.

Tony

@p5pRT
Copy link
Author

p5pRT commented Oct 19, 2015

The RT System itself - Status changed from 'new' to 'open'

@p5pRT p5pRT closed this as completed Oct 19, 2015
@p5pRT
Copy link
Author

p5pRT commented Oct 19, 2015

@tonycoz - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant