Subject: | Premature (?) clearance of returning future? |
Date: | Wed, 2 Dec 2020 08:56:18 -0500 |
To: | bug-Future-AsyncAwait [...] rt.cpan.org |
From: | Felipe Gasper <felipe [...] felipegasper.com> |
I’m trying to add F::AA support to Promise::ES6 and Promise::XS. I have the interface done, and the tests all pass, but in practice I’m finding that F::AA leaves its returning futures to be reaped rather than holding onto a reference.
The issue appears to be this bit in AsyncAwait.xs:
-----
if(!SvWEAKREF(state->returning_future))
sv_rvweaken(state->returning_future);
-----
… in tandem with logic such as:
-----
my $resolver_cr;
my $p = Promise::ES6->new( sub { $resolver_cr = shift } );
async sub do_await {
my $p = shift;
return await $p;
}
do_await($p)->then( sub { print "got " . shift . $/ } );
Time::HiRes::sleep(0.1);
$resolver_cr->(5);
-----
Full examples, including patched Promise::ES6, are in this branch: https://github.com/FGasper/p5-Promise-ES6/tree/async_await
F::AA seems, by virtue of the weakening of state->returning_future, to expect the caller to hold on to the reference that do_await() returns. When I remove that weakening, my code works, but then 4 of F:AA’s tests in t/42unresolved.t break:
- 2 assertions expect to see a “lost its returning future” warning but instead see no warning. I’m not sure how important those assertions are.
- 2 other assertions concern refcounts on $@ and *@. These failures seem to indicate a leak caused by removing the weakening.
Now, there do appear to be other leaks in that test; the suspended states for “abandoned chain” and “abandoned subsequent on anon sub”, at least, also appear to be freed at global-destruct time.
========
Executive Summary:
1) If F::AA intends to require that callers hold their own references to the returned future/promise, should the Awaitable test suite add a test for that, and documentation be updated?
2) If F::AA does _not_ intend to require that, is it feasible to update F::AA to remove the need that seems apparent in the current release?
Thank you!