Subject: | ->wait_any Future going out of scope while processing dependents |
Seen a few of these, particularly with code using Net::Async::HTTP where the remote server closes the connection:
Can't call method "_mark_ready" on an undefined value at .../site_perl/5.24.0/Future.pm line 1665.
This is the $weakself->_mark_ready() call in ->wait_any.
I think what's happening is that the ->wait_any Future is going out of scope while the dependents are being processed, so we start out with a valid $weakself, but end up with undef by the end of that sub.
The attached patch may not be the right thing to do - maybe the future going out of scope is an invalid situation, and we should be flagging this the same way as cases such as void-context ->then?
Subject: | 2017-03-01-wait-any-weakself.patch |
diff --git a/lib/Future.pm b/lib/Future.pm
index c926bd2..5c7a4f3 100644
--- a/lib/Future.pm
+++ b/lib/Future.pm
@@ -1643,26 +1643,26 @@ sub wait_any
weaken( my $weakself = $self );
my $sub_on_ready = sub {
- return unless $weakself;
- return if $weakself->{result} or $weakself->{failure}; # don't recurse on child ->cancel
+ return unless my $self = $weakself;
+ return if $self->{result} or $self->{failure}; # don't recurse on child ->cancel
return if --$pending and $_[0]->{cancelled};
if( $_[0]->{cancelled} ) {
- $weakself->{failure} = [ "All component futures were cancelled" ];
+ $self->{failure} = [ "All component futures were cancelled" ];
}
elsif( $_[0]->{failure} ) {
- $weakself->{failure} = [ $_[0]->failure ];
+ $self->{failure} = [ $_[0]->failure ];
}
else {
- $weakself->{result} = [ $_[0]->get ];
+ $self->{result} = [ $_[0]->get ];
}
foreach my $sub ( @subs ) {
$sub->{ready} or $sub->cancel;
}
- $weakself->_mark_ready( "wait_any" );
+ $self->_mark_ready( "wait_any" );
};
foreach my $sub ( @subs ) {