Created
August 26, 2026 20:33
-
-
Save jjn1056/f2dbe746a598c6e6e23febb2dafc3f3e to your computer and use it in GitHub Desktop.
Using Future::OP with _DefaultImpl or not?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Hit this working on an async redis client - a pubsub message handler | |
| disconnects two connections, which cancels both their in-flight reads, | |
| and with the default impl that dies: | |
| Can't call method "fh" on an undefined value at Future/IO.pm line 890 | |
| Best I can tell the poll loop caches $npollers and then completes ready | |
| futures inside the loop, so when a continuation cancels other pending | |
| reads, on_cancel splices them out of @pollers behind the loop's back and | |
| the index runs off the end. | |
| Boiled it down to this. On the stock default impl it dies every time; | |
| run the same script with -MFuture::IO::Impl::IOAsync and it completes | |
| fine, so it looks specific to _DefaultImpl's poll loop: | |
| use v5.36; | |
| use Socket; | |
| use Future::IO; | |
| my (@rd, @wr); | |
| for (0..2) { | |
| socketpair my $r, my $w, AF_UNIX, SOCK_STREAM, PF_UNSPEC or die $!; | |
| push @rd, $r; | |
| push @wr, $w; | |
| } | |
| my @f = map { Future::IO->read($_, 10) } @rd; | |
| $f[0]->on_done(sub { $f[1]->cancel; $f[2]->cancel }); | |
| syswrite $wr[0], "hello"; | |
| $f[0]->get; | |
| say "completed without error"; | |
| I patched my local copy to collect the ready pollers during the scan and | |
| fire ->done after it finishes (with an is_ready guard) and that fixes the | |
| repro, plus my app's full test suite passes on it. Happy to send the | |
| patch if you want. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment