#!/usr/bin/perl use v5.14; use warnings; use Test::More; use Test::Refcount 0.09 import => [qw( is_refcount refcount )]; use Future; use Future::AsyncAwait; my $orig_cxstack_ix = Future::AsyncAwait::__cxstack_ix; my $file = quotemeta __FILE__; my $errgv_ref = \*@; async sub identity { return await $_[0]; } async sub func { my ( $f, @vals ) = @_; my $pad = "foo" . ref($f); my $x = 123; $x + 1 + [ "a", await identity $f ]; } # abandoned chain { my $f1 = Future->new; my $fret = func( $f1, 1, 2 ); undef $fret; pass( 'abandoned chain does not crash' ); } # abandoned subsequent (RT129303) { my $f1 = Future->new; my $fret = func( $f1, 3, 4 ); undef $fret; my $warnings = ""; { local $SIG{__WARN__} = sub { $warnings .= join "", @_ }; $f1->done; } pass( 'abandoned subsequent does not crash' ); like( $warnings, qr/^Suspended async sub main::func lost its returning future at $file line \d+/, 'warning from attempted resume' ); } # abandoned subsequent on anon sub { my $f1 = Future->new; my $fret = (async sub { await $f1 })->(); undef $fret; my $warnings = ""; { local $SIG{__WARN__} = sub { $warnings .= join "", @_ }; $f1->done; } pass( 'abandoned subsequent does not crash' ); like( $warnings, qr/^Suspended async sub CODE\(0x[0-9a-f]+\) in package main lost its returning future at $file line \d+/, 'warning from attempted resume' ); } # abandoned foreach loop (RT129320) { my $f1 = Future->new; my $fret = (async sub { foreach my $f ($f1) { await $f } })->(); undef $fret; pass( "abandoned foreach loop does not crash" ); } # abandoned local $@ { my $errsv_refcount = refcount(\$@); my $errgv_refcount = refcount($errgv_ref); my $f1 = Future->new; my $fret = (async sub { local $@; await $f1 })->(); undef $fret; undef $f1; pass( "abandoned local \$@ does not crash" ); is_refcount( \$@, $errsv_refcount, '$@ refcount preserved' ); is_refcount( $errgv_ref, $errgv_refcount, '*@ refcount preserved' ); } is( Future::AsyncAwait::__cxstack_ix, $orig_cxstack_ix, 'cxstack_ix did not grow during the test' ); done_testing;