Skip Menu |

This queue is for tickets about the POE CPAN distribution.

Report information
The Basics
Id: 69796
Status: resolved
Priority: 0/
Queue: POE

People
Owner: Nobody in particular
Requestors: oliverklozoff [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 1.311
Fixed in: (no value)



Subject: Failure of t/10_loops/04_drivers/01_sysrw.t on Win32 (v1_310-47-gaf6b204)
The commit >> 322bb80a55c74b2918bc << [1] which tried to simplify the implementation of nonblocking() causes the test to fail (or simply wait forever, due to a bug in write_until_pipe_full) on Win32. The problem is that the code that implements IO::Handle::blocking() on Win32 is completely wrong (see Perl bug #95586). blocking(0) turns ON blocking, blocking(1) turns OFF blocking. Fortunately, there is a completely portable workaround: blocking(), which normally returns the blocking status, turns OFF blocking on Win32. System information: POE: v1_310-47-gaf6b204 (9bcbb9098bf12139b4f80ef96650eafba3e1d95b) perl -v: This is perl 5, version 14, subversion 1 (v5.14.1) built for MSWin32-x64-multi-thread [ActivePerl] OS: Windows 2003 Server 64-bit Standard Edition
Subject: poe-sysrw-win32-testfix.patch
diff --git a/t/10_units/04_drivers/01_sysrw.t b/t/10_units/04_drivers/01_sysrw.t index ee709cc..6f50b7e 100644 --- a/t/10_units/04_drivers/01_sysrw.t +++ b/t/10_units/04_drivers/01_sysrw.t @@ -3,7 +3,7 @@ use strict; -use Test::More tests => 17; +use Test::More tests => 18; use POE::Pipe::OneWay; BEGIN { use_ok("POE::Driver::SysRW") } @@ -106,9 +106,11 @@ nonblocking($r); # Number of flushed octets == number of read octets. -{ my $flushed_count = write_until_pipe_is_full($d, $w); - my $read_count = read_until_pipe_is_empty($d, $r); +{ my ($flushed_count, $full) = write_until_pipe_is_full($d, $w); + my ($read_count) = read_until_pipe_is_empty($d, $r); + ok($full, "data successfully written"); + ok( $flushed_count == $read_count, "flushed $flushed_count octets == read $read_count octets" @@ -185,14 +187,19 @@ sub write_until_pipe_is_full { # Try to flush it. my $after_flush = $driver->flush($handle); + + $full = 1 if defined($after_flush) && $after_flush == 0; # Flushed amount. $flushed += $buffered - $after_flush; # The pipe is full if there's data after the flush. - last if $after_flush; + last if !defined($after_flush) || $after_flush; } + if (wantarray) { + return ($flushed, $full); + } return $flushed; } @@ -245,7 +252,7 @@ sub nonblocking { eval { binmode *$handle }; # Turn off blocking. - eval { $handle->blocking(0) }; + eval { $handle->blocking(0); $handle->blocking(); }; # Turn off buffering. CORE::select((CORE::select($handle), $| = 1)[0]);
On Mon Jul 25 17:14:01 2011, stevie-o wrote: Show quoted text
> The commit >> 322bb80a55c74b2918bc << [1] which tried to simplify the > implementation of nonblocking() causes the test to fail (or simply wait > forever, due to a bug in write_until_pipe_full) on Win32. > > The problem is that the code that implements IO::Handle::blocking() on > Win32 is completely wrong (see Perl bug #95586). blocking(0) turns ON > blocking, blocking(1) turns OFF blocking. > > Fortunately, there is a completely portable workaround: blocking(), > which normally returns the blocking status, turns OFF blocking on Win32.
Thank you for pointing this out. I don't think I'd have spotted it myself. Relying on blocking(Bool) being backwards or blocking() having a side effect seems short-lived. At some point, someone will fix one or both problems, and my work-around will break. As much as I wish I could delegate blocking() to someone else's library, I'm afraid I'll need to put the old code back for now. I'll do this in the next day or two, when I have a Windows machine online to test.
Subject: Re: [rt.cpan.org #69796] Failure of t/10_loops/04_drivers/01_sysrw.t on Win32 (v1_310-47-gaf6b204)
Date: Wed, 27 Jul 2011 11:08:23 -0400
To: bug-POE [...] rt.cpan.org
From: Stephen Oberholtzer <oliverklozoff [...] gmail.com>
Actually, I've already submitted a patch to Perl to fix *both* problems. My patch to POE takes this into consideration. So this is what happens: Today (on Win32), the *current* behavior of my patched test does: * blocking(0) => Turns on blocking * blocking() => Turns off blocking (achieving the original goal) On other OSes, it does: * blocking(0) => Turns off blocking * blocking() => Checks current blocking status (i.e. no-op) After my patch (or an equivalent) is accepted into Perl, the patched test will do: * blocking(0) => Turns off blocking * blocking() => Returns undef (i.e. no-op) (blocking() returns undef because as far as I can tell, there is no way to get Win32 to report back the nonblocking status of a socket) On Wed, Jul 27, 2011 at 2:53 AM, Rocco Caputo via RT <bug-POE@rt.cpan.org> wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=69796 > > > On Mon Jul 25 17:14:01 2011, stevie-o wrote:
>> The commit >> 322bb80a55c74b2918bc << [1] which tried to simplify the >> implementation of nonblocking() causes the test to fail (or simply wait >> forever, due to a bug in write_until_pipe_full) on Win32. >> >> The problem is that the code that implements IO::Handle::blocking() on >> Win32 is completely wrong (see Perl bug #95586).  blocking(0) turns ON >> blocking, blocking(1) turns OFF blocking. >> >> Fortunately, there is a completely portable workaround: blocking(), >> which normally returns the blocking status, turns OFF blocking on Win32.
> > Thank you for pointing this out.  I don't think I'd have spotted it myself. > > Relying on blocking(Bool) being backwards or blocking() having a side > effect seems short-lived.  At some point, someone will fix one or both > problems, and my work-around will break. > > As much as I wish I could delegate blocking() to someone else's library, > I'm afraid I'll need to put the old code back for now.  I'll do this in > the next day or two, when I have a Windows machine online to test. > >
-- -- Stevie-O Real programmers use COPY CON PROGRAM.EXE
On Wed Jul 27 11:08:36 2011, stevie-o wrote: Show quoted text
> Actually, I've already submitted a patch to Perl to fix *both* > problems. My patch to POE takes this into consideration.
Thanks for the clarification. I committed a modified version of your patch as revision a4b961a547bb32d4bd9057fb9e0501aa138f602a ... It'll be in the next release. I had to remove your test for a full flush. Many systems only allow partial flushes. For example, only 8 KB would fit on one of my systems. not ok 12 - data successfully written # Failed test 'data successfully written' # at t/10_units/04_drivers/01_sysrw.t line 112. ok 13 - flushed 8192 octets == read 8192 octets ... ok 18 - put() sets $! nonzero on error # Looks like you failed 1 test of 18.