Skip Menu |

This queue is for tickets about the IO-Async CPAN distribution.

Report information
The Basics
Id: 71764
Status: open
Priority: 0/
Queue: IO-Async

People
Owner: Nobody in particular
Requestors: leonerd-cpan [...] leonerd.org.uk
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 0.44
Fixed in: (no value)



Subject: $stream->close does not invoke current on_read handler with $closed==true
$ cat rt-todo.pl #!/usr/bin/perl use strict; use warnings; use IO::Async::Stream; use IO::Async::Loop; my $loop = IO::Async::Loop->new; my ( $S1, $S2 ) = $loop->socketpair; my $stream = IO::Async::Stream->new( handle => $S1, on_read => sub { print STDERR "on_read: @_\n" }, on_closed => sub { print STDERR "on_closed: @_\n" }, ); $loop->add( $stream ); $stream->close; $loop->loop_forever; $ perl rt-todo.pl on_closed: IO::Async::Stream=HASH(0x140f910) ^C #### Expected first to see on_read: IO::Async::Stream=HASH(0x...) SCALAR(0x...) 1 -- Paul Evans
This still happens with 0.64, updated test case to use IO::Async::OS->socketpair since that's no longer available on $loop.
Subject: 2015-02-11-rt71764.pl
#!/usr/bin/perl use strict; use warnings; use IO::Async::Stream; use IO::Async::Loop; my $loop = IO::Async::Loop->new; my ( $S1, $S2 ) = IO::Async::OS->socketpair; my $stream = IO::Async::Stream->new( handle => $S1, on_read => sub { print STDERR "on_read: @_\n" }, on_closed => sub { print STDERR "on_closed: @_\n" }, ); $loop->add( $stream ); $stream->close; $loop->run;
I'm beginning to rethink this one. An initial naive implementation by just invoking the 'on_read' handler during ->close means that 'on_read' is invoked twice if a real read() operation returned 0, indicating a genuine EOF from outside. This has an annoying knock-on effect of causing $loop->spawn_child's on_exit to run twice, causing Future double-done errors in IaProcess, and from there everything falls apart. I'm sure this could be worked-around somehow, but it starts to suggest it might not be the right route. Given as a received EOF /already/ causes an on_closed event to happen right afterwards, there's no need for ->close to invoke on_read with $eof=1, because any application code ought to be using on_closed for that sort of handling anyway. The only reason $eof is given to on_read is to allow an early-abort if data is still in the buffer but there's no point replying to it (e.g. HTTP server). I suspec therefore it's actually better not to implement this one. -- Paul Evans