Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package perl-IO-Async for openSUSE:Factory checked in at 2026-06-09 14:26:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-IO-Async (Old) and /work/SRC/openSUSE:Factory/.perl-IO-Async.new.2375 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-IO-Async" Tue Jun 9 14:26:02 2026 rev:10 rq:1358066 version:0.805.0 Changes: -------- --- /work/SRC/openSUSE:Factory/perl-IO-Async/perl-IO-Async.changes 2025-05-26 18:37:18.023870113 +0200 +++ /work/SRC/openSUSE:Factory/.perl-IO-Async.new.2375/perl-IO-Async.changes 2026-06-09 14:28:28.092829943 +0200 @@ -1,0 +2,20 @@ +Wed Jan 21 05:48:46 UTC 2026 - Tina Müller <[email protected]> + +- updated to 0.805.0 (0.805) + see /usr/share/doc/packages/perl-IO-Async/Changes + + 0.805 2026-01-19 + [CHANGES] + * Document and test that separate `->watch_io` calls for read and + write-readiness work correctly + * Implement (most of) the `Future::IO->poll` API in + `Future::IO::Impl::IOAsync` + + [BUGFIXES] + * Ensure that `IO::Async::File` copes correctly with missing files + (RT136578) + * Test2's bail_out() is named in lowercase, not BAIL_OUT. + * Update the `time_between()` test helper function to be better + suited to `Test2` + +------------------------------------------------------------------- Old: ---- IO-Async-0.804.tar.gz New: ---- IO-Async-0.805.tar.gz README.md _scmsync.obsinfo build.specials.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-IO-Async.spec ++++++ --- /var/tmp/diff_new_pack.jp8qqG/_old 2026-06-09 14:28:30.076912290 +0200 +++ /var/tmp/diff_new_pack.jp8qqG/_new 2026-06-09 14:28:30.092912954 +0200 @@ -1,7 +1,7 @@ # # spec file for package perl-IO-Async # -# Copyright (c) 2025 SUSE LLC +# Copyright (c) 2026 SUSE LLC and contributors # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,25 +18,26 @@ %define cpan_name IO-Async Name: perl-IO-Async -Version: 0.804.0 +Version: 0.805.0 Release: 0 -# 0.804 -> normalize -> 0.804.0 -%define cpan_version 0.804 +# 0.805 -> normalize -> 0.805.0 +%define cpan_version 0.805 License: Artistic-1.0 OR GPL-1.0-or-later Summary: Asynchronous event-driven programming URL: https://metacpan.org/release/%{cpan_name} Source0: https://cpan.metacpan.org/authors/id/P/PE/PEVANS/%{cpan_name}-%{cpan_version}.tar.gz Source1: cpanspec.yml +Source100: README.md BuildArch: noarch BuildRequires: perl BuildRequires: perl-macros BuildRequires: perl(Future) >= 0.440 BuildRequires: perl(Future::Utils) >= 0.180 -BuildRequires: perl(Module::Build) >= 0.4004 +BuildRequires: perl(Module::Build) >= 0.400.400 BuildRequires: perl(Socket) >= 2.007 BuildRequires: perl(Struct::Dumb) BuildRequires: perl(Test2::V0) >= 0.000149 -BuildRequires: perl(Test::Future::IO::Impl) +BuildRequires: perl(Test::Future::IO::Impl) >= 0.170 BuildRequires: perl(Test::Metrics::Any) Requires: perl(Future) >= 0.440 Requires: perl(Future::Utils) >= 0.180 ++++++ IO-Async-0.804.tar.gz -> IO-Async-0.805.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/Build.PL new/IO-Async-0.805/Build.PL --- old/IO-Async-0.804/Build.PL 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/Build.PL 2026-01-19 16:19:46.000000000 +0100 @@ -26,7 +26,7 @@ }, test_requires => { 'File::Temp' => 0, - 'Test::Future::IO::Impl' => 0, + 'Test::Future::IO::Impl' => '0.17', 'Test::Metrics::Any' => 0, 'Test2::V0' => '0.000149', }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/Changes new/IO-Async-0.805/Changes --- old/IO-Async-0.804/Changes 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/Changes 2026-01-19 16:19:46.000000000 +0100 @@ -1,5 +1,19 @@ Revision history for IO-Async +0.805 2026-01-19 + [CHANGES] + * Document and test that separate `->watch_io` calls for read and + write-readiness work correctly + * Implement (most of) the `Future::IO->poll` API in + `Future::IO::Impl::IOAsync` + + [BUGFIXES] + * Ensure that `IO::Async::File` copes correctly with missing files + (RT136578) + * Test2's bail_out() is named in lowercase, not BAIL_OUT. + * Update the `time_between()` test helper function to be better + suited to `Test2` + 0.804 2025-04-22 [CHANGES] * Add extra LoopTests tests for IO and timer operation after a diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/LICENSE new/IO-Async-0.805/LICENSE --- old/IO-Async-0.804/LICENSE 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/LICENSE 2026-01-19 16:19:46.000000000 +0100 @@ -1,4 +1,4 @@ -This software is copyright (c) 2025 by Paul Evans <[email protected]>. +This software is copyright (c) 2026 by Paul Evans <[email protected]>. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. @@ -12,7 +12,7 @@ --- The GNU General Public License, Version 1, February 1989 --- -This software is Copyright (c) 2025 by Paul Evans <[email protected]>. +This software is Copyright (c) 2026 by Paul Evans <[email protected]>. This is free software, licensed under: @@ -272,7 +272,7 @@ --- The Perl Artistic License 1.0 --- -This software is Copyright (c) 2025 by Paul Evans <[email protected]>. +This software is Copyright (c) 2026 by Paul Evans <[email protected]>. This is free software, licensed under: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/META.json new/IO-Async-0.805/META.json --- old/IO-Async-0.804/META.json 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/META.json 2026-01-19 16:19:46.000000000 +0100 @@ -41,7 +41,7 @@ "requires" : { "File::Temp" : "0", "Test2::V0" : "0.000149", - "Test::Future::IO::Impl" : "0", + "Test::Future::IO::Impl" : "0.17", "Test::Metrics::Any" : "0" } } @@ -49,151 +49,151 @@ "provides" : { "Future::IO::Impl::IOAsync" : { "file" : "lib/Future/IO/Impl/IOAsync.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async" : { "file" : "lib/IO/Async.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Channel" : { "file" : "lib/IO/Async/Channel.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Debug" : { "file" : "lib/IO/Async/Debug.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::File" : { "file" : "lib/IO/Async/File.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::FileStream" : { "file" : "lib/IO/Async/FileStream.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Function" : { "file" : "lib/IO/Async/Function.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Future" : { "file" : "lib/IO/Async/Future.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Handle" : { "file" : "lib/IO/Async/Handle.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Internals::ChildManager" : { "file" : "lib/IO/Async/Internals/ChildManager.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Internals::FunctionWorker" : { "file" : "lib/IO/Async/Internals/FunctionWorker.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Listener" : { "file" : "lib/IO/Async/Listener.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Loop" : { "file" : "lib/IO/Async/Loop.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Loop::Poll" : { "file" : "lib/IO/Async/Loop/Poll.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Loop::Select" : { "file" : "lib/IO/Async/Loop/Select.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::LoopTests" : { "file" : "lib/IO/Async/LoopTests.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Metrics" : { "file" : "lib/IO/Async/Metrics.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Notifier" : { "file" : "lib/IO/Async/Notifier.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::OS" : { "file" : "lib/IO/Async/OS.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::OS::MSWin32" : { "file" : "lib/IO/Async/OS/MSWin32.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::OS::cygwin" : { "file" : "lib/IO/Async/OS/cygwin.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::OS::linux" : { "file" : "lib/IO/Async/OS/linux.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::PID" : { "file" : "lib/IO/Async/PID.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Process" : { "file" : "lib/IO/Async/Process.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Protocol" : { "file" : "lib/IO/Async/Protocol.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Protocol::LineStream" : { "file" : "lib/IO/Async/Protocol/LineStream.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Protocol::Stream" : { "file" : "lib/IO/Async/Protocol/Stream.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Resolver" : { "file" : "lib/IO/Async/Resolver.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Routine" : { "file" : "lib/IO/Async/Routine.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Signal" : { "file" : "lib/IO/Async/Signal.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Socket" : { "file" : "lib/IO/Async/Socket.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Stream" : { "file" : "lib/IO/Async/Stream.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Test" : { "file" : "lib/IO/Async/Test.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Timer" : { "file" : "lib/IO/Async/Timer.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Timer::Absolute" : { "file" : "lib/IO/Async/Timer/Absolute.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Timer::Countdown" : { "file" : "lib/IO/Async/Timer/Countdown.pm", - "version" : "0.804" + "version" : "0.805" }, "IO::Async::Timer::Periodic" : { "file" : "lib/IO/Async/Timer/Periodic.pm", - "version" : "0.804" + "version" : "0.805" } }, "release_status" : "stable", @@ -203,6 +203,6 @@ ], "x_IRC" : "irc://irc.perl.org/#io-async" }, - "version" : "0.804", + "version" : "0.805", "x_serialization_backend" : "JSON::PP version 4.16" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/META.yml new/IO-Async-0.805/META.yml --- old/IO-Async-0.804/META.yml 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/META.yml 2026-01-19 16:19:46.000000000 +0100 @@ -5,7 +5,7 @@ build_requires: File::Temp: '0' Test2::V0: '0.000149' - Test::Future::IO::Impl: '0' + Test::Future::IO::Impl: '0.17' Test::Metrics::Any: '0' configure_requires: Module::Build: '0.4004' @@ -19,115 +19,115 @@ provides: Future::IO::Impl::IOAsync: file: lib/Future/IO/Impl/IOAsync.pm - version: '0.804' + version: '0.805' IO::Async: file: lib/IO/Async.pm - version: '0.804' + version: '0.805' IO::Async::Channel: file: lib/IO/Async/Channel.pm - version: '0.804' + version: '0.805' IO::Async::Debug: file: lib/IO/Async/Debug.pm - version: '0.804' + version: '0.805' IO::Async::File: file: lib/IO/Async/File.pm - version: '0.804' + version: '0.805' IO::Async::FileStream: file: lib/IO/Async/FileStream.pm - version: '0.804' + version: '0.805' IO::Async::Function: file: lib/IO/Async/Function.pm - version: '0.804' + version: '0.805' IO::Async::Future: file: lib/IO/Async/Future.pm - version: '0.804' + version: '0.805' IO::Async::Handle: file: lib/IO/Async/Handle.pm - version: '0.804' + version: '0.805' IO::Async::Internals::ChildManager: file: lib/IO/Async/Internals/ChildManager.pm - version: '0.804' + version: '0.805' IO::Async::Internals::FunctionWorker: file: lib/IO/Async/Internals/FunctionWorker.pm - version: '0.804' + version: '0.805' IO::Async::Listener: file: lib/IO/Async/Listener.pm - version: '0.804' + version: '0.805' IO::Async::Loop: file: lib/IO/Async/Loop.pm - version: '0.804' + version: '0.805' IO::Async::Loop::Poll: file: lib/IO/Async/Loop/Poll.pm - version: '0.804' + version: '0.805' IO::Async::Loop::Select: file: lib/IO/Async/Loop/Select.pm - version: '0.804' + version: '0.805' IO::Async::LoopTests: file: lib/IO/Async/LoopTests.pm - version: '0.804' + version: '0.805' IO::Async::Metrics: file: lib/IO/Async/Metrics.pm - version: '0.804' + version: '0.805' IO::Async::Notifier: file: lib/IO/Async/Notifier.pm - version: '0.804' + version: '0.805' IO::Async::OS: file: lib/IO/Async/OS.pm - version: '0.804' + version: '0.805' IO::Async::OS::MSWin32: file: lib/IO/Async/OS/MSWin32.pm - version: '0.804' + version: '0.805' IO::Async::OS::cygwin: file: lib/IO/Async/OS/cygwin.pm - version: '0.804' + version: '0.805' IO::Async::OS::linux: file: lib/IO/Async/OS/linux.pm - version: '0.804' + version: '0.805' IO::Async::PID: file: lib/IO/Async/PID.pm - version: '0.804' + version: '0.805' IO::Async::Process: file: lib/IO/Async/Process.pm - version: '0.804' + version: '0.805' IO::Async::Protocol: file: lib/IO/Async/Protocol.pm - version: '0.804' + version: '0.805' IO::Async::Protocol::LineStream: file: lib/IO/Async/Protocol/LineStream.pm - version: '0.804' + version: '0.805' IO::Async::Protocol::Stream: file: lib/IO/Async/Protocol/Stream.pm - version: '0.804' + version: '0.805' IO::Async::Resolver: file: lib/IO/Async/Resolver.pm - version: '0.804' + version: '0.805' IO::Async::Routine: file: lib/IO/Async/Routine.pm - version: '0.804' + version: '0.805' IO::Async::Signal: file: lib/IO/Async/Signal.pm - version: '0.804' + version: '0.805' IO::Async::Socket: file: lib/IO/Async/Socket.pm - version: '0.804' + version: '0.805' IO::Async::Stream: file: lib/IO/Async/Stream.pm - version: '0.804' + version: '0.805' IO::Async::Test: file: lib/IO/Async/Test.pm - version: '0.804' + version: '0.805' IO::Async::Timer: file: lib/IO/Async/Timer.pm - version: '0.804' + version: '0.805' IO::Async::Timer::Absolute: file: lib/IO/Async/Timer/Absolute.pm - version: '0.804' + version: '0.805' IO::Async::Timer::Countdown: file: lib/IO/Async/Timer/Countdown.pm - version: '0.804' + version: '0.805' IO::Async::Timer::Periodic: file: lib/IO/Async/Timer/Periodic.pm - version: '0.804' + version: '0.805' recommends: IO::Socket::IP: '0' requires: @@ -145,5 +145,5 @@ resources: IRC: irc://irc.perl.org/#io-async license: http://dev.perl.org/licenses/ -version: '0.804' +version: '0.805' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/Future/IO/Impl/IOAsync.pm new/IO-Async-0.805/lib/Future/IO/Impl/IOAsync.pm --- old/IO-Async-0.804/lib/Future/IO/Impl/IOAsync.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/Future/IO/Impl/IOAsync.pm 2026-01-19 16:19:46.000000000 +0100 @@ -1,13 +1,16 @@ # You may distribute under the terms of either the GNU General Public License # or the Artistic License (the same terms as Perl itself) # -# (C) Paul Evans, 2019-2024 -- [email protected] +# (C) Paul Evans, 2019-2026 -- [email protected] -package Future::IO::Impl::IOAsync 0.804; +package Future::IO::Impl::IOAsync 0.805; use v5.14; use warnings; use base qw( Future::IO::ImplBase ); +BEGIN { Future::IO::ImplBase->VERSION( '0.19' ); } + +use Future::IO qw( POLLIN POLLOUT POLLHUP ); =head1 NAME @@ -15,6 +18,8 @@ =head1 DESCRIPTION +=for highlighter language=perl + This module provides an implementation for L<Future::IO> which uses L<IO::Async>. @@ -27,6 +32,18 @@ my $f = Future::IO->sleep(5); ... +=head1 LIMITATIONS + +This module only provides a limited subset of the L<Future::IO/poll> method +API. It fully handles C<POLLIN> and C<POLLOUT> conditions, but is not able to +report on C<POLLHUP> and C<POLLERR> events. + +When a filehandle is at hangup condition it is reported as only C<POLLIN>, and +when at error condition it is reported as only C<POLLOUT>. This I<should> be +sufficient for most purposes, and works fine for internally providing +asynchronous reading and writing on regular filehandles, but may cause some +odd behaviours if you are attempting to detect those conditions directly. + =cut use IO::Async::Loop; @@ -43,75 +60,66 @@ return ( $loop //= IO::Async::Loop->new )->delay_future( after => $secs ); } -my %watching_read_by_fileno; # {fileno} => [@futures] +my %futures_read_by_fileno; # {fileno} => [@futures] +my %futures_write_by_fileno; # {fileno} => [@futures] -# Not (yet) part of Future::IO API but it seems a useful way to build this -sub ready_for_read +sub poll { shift; - my ( $fh ) = @_; - - my $watching = $watching_read_by_fileno{ $fh->fileno } //= []; - - $loop //= IO::Async::Loop->new; - my $f = $loop->new_future; - - my $was = scalar @$watching; - push @$watching, $f; - - return $f if $was; - - $loop->watch_io( - handle => $fh, - on_read_ready => sub { - $watching->[0]->done; - shift @$watching; - - return if scalar @$watching; - - $loop->unwatch_io( - handle => $fh, - on_read_ready => 1, - ); - delete $watching_read_by_fileno{ $fh->fileno }; - }, - ); - - return $f; -} - -my %watching_write_by_fileno; # {fileno} => [@futures] - -sub ready_for_write -{ - shift; - my ( $fh ) = @_; - - my $watching = $watching_write_by_fileno{ $fh->fileno } //= []; - - $loop //= IO::Async::Loop->new; - my $f = $loop->new_future; - - my $was = scalar @$watching; - push @$watching, $f; + my ( $fh, $events ) = @_; - return $f if $was; + my $fileno = $fh->fileno; - $loop->watch_io( - handle => $fh, - on_write_ready => sub { - $watching->[0]->done; - shift @$watching; + my $f = ( $loop //= IO::Async::Loop->new )->new_future; - return if scalar @$watching; + if( $events & (POLLIN|POLLHUP) ) { + my $futures = $futures_read_by_fileno{$fileno} //= []; - $loop->unwatch_io( - handle => $fh, - on_write_ready => 1, - ); - delete $watching_write_by_fileno{ $fh->fileno }; - }, - ); + my $was = scalar @$futures; + push @$futures, $f; + + # We can't watch for on_hangup as well here because most loop + # implementations will invoke that *as well as* on_read_ready, but + # only afterwards. That makes it difficult to report POLLHUP conditions + # properly. + $loop->watch_io( + handle => $fh, + on_read_ready => sub { + $futures->[0]->done( POLLIN ); + shift @$futures; + + return if scalar @$futures; + + $loop->unwatch_io( + handle => $fh, + on_read_ready => 1, + ); + delete $futures_read_by_fileno{$fileno}; + }, + ) if !$was; + } + if( $events & POLLOUT ) { + my $futures = $futures_write_by_fileno{$fileno} //= []; + + my $was = scalar @$futures; + push @$futures, $f; + + $loop->watch_io( + handle => $fh, + on_write_ready => sub { + $futures->[0]->done( POLLOUT ); + shift @$futures; + + return if scalar @$futures; + + $loop->unwatch_io( + handle => $fh, + on_write_ready => 1, + ); + delete $futures_write_by_fileno{$fileno}; + }, + ) if !$was; + } return $f; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Channel.pm new/IO-Async-0.805/lib/IO/Async/Channel.pm --- old/IO-Async-0.804/lib/IO/Async/Channel.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Channel.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2011-2024 -- [email protected] -package IO::Async::Channel 0.804; +package IO::Async::Channel 0.805; use v5.14; use warnings; @@ -19,6 +19,8 @@ =head1 DESCRIPTION +=for highlighter language=perl + A C<IO::Async::Channel> object allows Perl values to be passed into or out of an L<IO::Async::Routine>. It is intended to be used primarily with a Routine object rather than independently. For more detail and examples on how to use diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Debug.pm new/IO-Async-0.805/lib/IO/Async/Debug.pm --- old/IO-Async-0.804/lib/IO/Async/Debug.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Debug.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2015-2024 -- [email protected] -package IO::Async::Debug 0.804; +package IO::Async::Debug 0.805; use v5.14; use warnings; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/File.pm new/IO-Async-0.805/lib/IO/Async/File.pm --- old/IO-Async-0.804/lib/IO/Async/File.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/File.pm 2026-01-19 16:19:46.000000000 +0100 @@ -1,9 +1,9 @@ # You may distribute under the terms of either the GNU General Public License # or the Artistic License (the same terms as Perl itself) # -# (C) Paul Evans, 2012-2024 -- [email protected] +# (C) Paul Evans, 2012-2025 -- [email protected] -package IO::Async::File 0.804; +package IO::Async::File 0.805; use v5.14; use warnings; @@ -22,6 +22,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + use IO::Async::File; use IO::Async::Loop; @@ -51,6 +53,10 @@ regular file. It is possible to watch anything that C<stat(2)> may be called on, such as directories or other filesystem entities. +I<Since version 0.805> a named file does not necessarily need to exist. If it +is not present, all its C<stat()> fields are treated as undefined; events will +be invoked when it becomes present or is removed, in addition to any changes. + =cut =head1 EVENTS @@ -68,7 +74,8 @@ Invoked when each of the individual C<stat()> fields have changed. All the C<stat()> fields are supported apart from C<blocks> and C<blksize>. Each is -passed the new and old values of the field. +passed the new and old values of the field. Either field may be C<undef> if +the file did not or currently does not exist. =head2 on_devino_changed $new_stat, $old_stat @@ -80,7 +87,8 @@ =head2 on_stat_changed $new_stat, $old_stat Invoked when any of the C<stat()> fields have changed. It is passed two -L<File::stat> instances containing the old and new C<stat()> fields. +L<File::stat> instances containing the old and new C<stat()> fields. Either +value may be C<undef> if the file did not or currently does not exist. =cut @@ -159,9 +167,12 @@ my $path = $self->{filename}; - open $self->{handle}, "<", $path or croak "Cannot open $path for reading - $!"; - - $self->{last_stat} = stat $self->{handle}; + if( open $self->{handle}, "<", $path ) { + $self->{last_stat} = stat $self->{handle}; + } + else { + undef $self->{last_stat}; + } } sub on_tick @@ -171,15 +182,23 @@ my $old = $self->{last_stat}; my $new = stat( defined $self->{filename} ? $self->{filename} : $self->{handle} ); + # If it didn't and still doesn't exist, nothing to do + defined $old or defined $new or + return; + + # From here onwards, one of $old or $new might be undef + my $any_changed; foreach my $stat ( @STATS ) { - next if $old->$stat == $new->$stat; + next if $old and $new and $old->$stat == $new->$stat; $any_changed++; - $self->maybe_invoke_event( "on_${stat}_changed", $new->$stat, $old->$stat ); + $self->maybe_invoke_event( "on_${stat}_changed", + ( $new ? $new->$stat : undef ), + ( $old ? $old->$stat : undef ) ); } - if( $old->dev != $new->dev or $old->ino != $new->ino ) { + if( !$old or !$new or $old->dev != $new->dev or $old->ino != $new->ino ) { $self->maybe_invoke_event( on_devino_changed => $new, $old ); $self->_reopen_file; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/FileStream.pm new/IO-Async-0.805/lib/IO/Async/FileStream.pm --- old/IO-Async-0.804/lib/IO/Async/FileStream.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/FileStream.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2011-2024 -- [email protected] -package IO::Async::FileStream 0.804; +package IO::Async::FileStream 0.805; use v5.14; use warnings; @@ -21,6 +21,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + use IO::Async::FileStream; use IO::Async::Loop; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Function.pm new/IO-Async-0.805/lib/IO/Async/Function.pm --- old/IO-Async-0.804/lib/IO/Async/Function.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Function.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2011-2024 -- [email protected] -package IO::Async::Function 0.804; +package IO::Async::Function 0.805; use v5.14; use warnings; @@ -25,6 +25,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + use Future::AsyncAwait; use IO::Async::Function; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Future.pm new/IO-Async-0.805/lib/IO/Async/Future.pm --- old/IO-Async-0.804/lib/IO/Async/Future.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Future.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2013-2024 -- [email protected] -package IO::Async::Future 0.804; +package IO::Async::Future 0.805; use v5.14; use warnings; @@ -23,6 +23,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + use Future::AsyncAwait; use IO::Async::Loop; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Handle.pm new/IO-Async-0.805/lib/IO/Async/Handle.pm --- old/IO-Async-0.804/lib/IO/Async/Handle.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Handle.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2006-2024 -- [email protected] -package IO::Async::Handle 0.804; +package IO::Async::Handle 0.805; use v5.14; use warnings; @@ -24,6 +24,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + This class is likely not to be used directly, because subclasses of it exist to handle more specific cases. Here is an example of how it would be used to watch a listening socket for new connections. In real code, it is likely that diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Internals/ChildManager.pm new/IO-Async-0.805/lib/IO/Async/Internals/ChildManager.pm --- old/IO-Async-0.804/lib/IO/Async/Internals/ChildManager.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Internals/ChildManager.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2007-2024 -- [email protected] -package IO::Async::Internals::ChildManager 0.804; +package IO::Async::Internals::ChildManager 0.805; use v5.14; use warnings; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Internals/FunctionWorker.pm new/IO-Async-0.805/lib/IO/Async/Internals/FunctionWorker.pm --- old/IO-Async-0.804/lib/IO/Async/Internals/FunctionWorker.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Internals/FunctionWorker.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2011-2024 -- [email protected] -package IO::Async::Internals::FunctionWorker 0.804; +package IO::Async::Internals::FunctionWorker 0.805; use v5.14; use warnings; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Listener.pm new/IO-Async-0.805/lib/IO/Async/Listener.pm --- old/IO-Async-0.804/lib/IO/Async/Listener.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Listener.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2008-2024 -- [email protected] -package IO::Async::Listener 0.804; +package IO::Async::Listener 0.805; use v5.14; use warnings; @@ -26,6 +26,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + use Future::AsyncAwait; use IO::Async::Listener; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Loop/Poll.pm new/IO-Async-0.805/lib/IO/Async/Loop/Poll.pm --- old/IO-Async-0.804/lib/IO/Async/Loop/Poll.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Loop/Poll.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2007-2024 -- [email protected] -package IO::Async::Loop::Poll 0.804; +package IO::Async::Loop::Poll 0.805; use v5.14; use warnings; @@ -41,6 +41,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + Normally an instance of this class would not be directly constructed by a program. It may however, be useful for runinng L<IO::Async> with an existing program already using an C<IO::Poll> object. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Loop/Select.pm new/IO-Async-0.805/lib/IO/Async/Loop/Select.pm --- old/IO-Async-0.804/lib/IO/Async/Loop/Select.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Loop/Select.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2007-2024 -- [email protected] -package IO::Async::Loop::Select 0.804; +package IO::Async::Loop::Select 0.805; use v5.14; use warnings; @@ -32,6 +32,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + Normally an instance of this class would not be directly constructed by a program. It may however, be useful for runinng L<IO::Async> with an existing program already using a C<select> call. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Loop.pm new/IO-Async-0.805/lib/IO/Async/Loop.pm --- old/IO-Async-0.804/lib/IO/Async/Loop.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Loop.pm 2026-01-19 16:19:46.000000000 +0100 @@ -1,9 +1,9 @@ # You may distribute under the terms of either the GNU General Public License # or the Artistic License (the same terms as Perl itself) # -# (C) Paul Evans, 2007-2024 -- [email protected] +# (C) Paul Evans, 2007-2025 -- [email protected] -package IO::Async::Loop 0.804; +package IO::Async::Loop 0.805; use v5.14; use warnings; @@ -88,6 +88,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + use IO::Async::Stream; use IO::Async::Timer::Countdown; @@ -2450,6 +2452,11 @@ enabled by this method. This will ensure that any subsequent C<sysread>, C<syswrite>, or similar will not block on the filehandle. +I<Since version 0.805> it is permitted to watch for read-readiness and +write-readiness of the same filehandle via two separate calls to this method. +Prior versions may have implemented it, but it was not specifically documented +as being permitted, nor subject to integration testing. + =cut # This class specifically does NOT implement this method, so that subclasses @@ -2699,7 +2706,7 @@ =head2 unwatch_time - $loop->unwatch_time( $id ) + $loop->unwatch_time( $id ); Removes a timer callback previously created by C<watch_time>. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/LoopTests.pm new/IO-Async-0.805/lib/IO/Async/LoopTests.pm --- old/IO-Async-0.804/lib/IO/Async/LoopTests.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/LoopTests.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2009-2025 -- [email protected] -package IO::Async::LoopTests 0.804; +package IO::Async::LoopTests 0.805; use v5.14; use warnings; @@ -40,6 +40,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + use IO::Async::LoopTests; run_tests( 'IO::Async::Loop::Shiney', 'io' ); @@ -90,7 +92,7 @@ eval { require $file }; if( $@ ) { - BAIL_OUT( "Unable to load $testclass - $@" ); + bail_out( "Unable to load $testclass - $@" ); } foreach my $test ( @tests ) { @@ -130,15 +132,19 @@ { my ( $code, $lower, $upper, $name ) = @_; - my $start = time; - $code->(); - my $took = ( time - $start ) / AUT; - - cmp_ok( $took, '>=', $lower, "$name took at least $lower seconds" ) if defined $lower; - cmp_ok( $took, '<=', $upper * 3, "$name took no more than $upper seconds" ) if defined $upper; - if( $took > $upper and $took <= $upper * 3 ) { - diag( "$name took longer than $upper seconds - this may just be an indication of a busy testing machine rather than a bug" ); - } + Test2::API::context_do { + my $ctx = shift;; + + my $start = time; + $code->(); + my $took = ( time - $start ) / AUT; + + $ctx->ok( $took >= $lower, "$name took at least $lower seconds" ) if defined $lower; + $ctx->ok( $took <= $upper * 3, "$name took no more than $upper seconds" ) if defined $upper; + if( $took > $upper and $took <= $upper * 3 ) { + $ctx->note( "$name took longer than $upper seconds - this may just be an indication of a busy testing machine rather than a bug" ); + } + }; } =head1 TEST SUITES @@ -240,6 +246,44 @@ ); } + # Check that read- and write-readiness can be watched via two separate + # ->watch_io calls on the same handle + { + my ( $S1, $S2 ) = IO::Async::OS->socketpair or die "Cannot create socket pair - $!"; + $_->blocking( 0 ) for $S1, $S2; + + foreach my $first (qw( read write )) { + my $readready = 0; + my $writeready = 0; + + $loop->watch_io( + handle => $S1, + on_read_ready => sub { $readready = 1 }, + ) if $first eq "read"; + $loop->watch_io( + handle => $S1, + on_write_ready => sub { $writeready = 1 }, + ); + $loop->watch_io( + handle => $S1, + on_read_ready => sub { $readready = 1 }, + ) if $first eq "write"; + + $S2->syswrite( "data\n" ); + + $loop->loop_once( 0.1 ) for 1..2; + + ok( $readready, '$readready after '.$first.' first split read+write watch' ); + ok( $writeready, '$writeready after '.$first.' first split read+write watch' ); + + $loop->unwatch_io( + handle => $S1, + on_read_ready => 1, + on_write_ready => 1, + ); + } + } + # HUP of pipe - can be different to sockets on some architectures { my ( $Prd, $Pwr ) = IO::Async::OS->pipepair or die "Cannot pipepair - $!"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Metrics.pm new/IO-Async-0.805/lib/IO/Async/Metrics.pm --- old/IO-Async-0.804/lib/IO/Async/Metrics.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Metrics.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2020-2024 -- [email protected] -package IO::Async::Metrics 0.804; +package IO::Async::Metrics 0.805; use v5.14; use warnings; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Notifier.pm new/IO-Async-0.805/lib/IO/Async/Notifier.pm --- old/IO-Async-0.804/lib/IO/Async/Notifier.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Notifier.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2006-2024 -- [email protected] -package IO::Async::Notifier 0.804; +package IO::Async::Notifier 0.805; use v5.14; use warnings; @@ -24,6 +24,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + Usually not directly used by a program, but one valid use case may be: use IO::Async::Notifier; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/OS/MSWin32.pm new/IO-Async-0.805/lib/IO/Async/OS/MSWin32.pm --- old/IO-Async-0.804/lib/IO/Async/OS/MSWin32.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/OS/MSWin32.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2012-2013 -- [email protected] -package IO::Async::OS::MSWin32 0.804; +package IO::Async::OS::MSWin32 0.805; use v5.14; use warnings; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/OS/cygwin.pm new/IO-Async-0.805/lib/IO/Async/OS/cygwin.pm --- old/IO-Async-0.804/lib/IO/Async/OS/cygwin.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/OS/cygwin.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2013-2024 -- [email protected] -package IO::Async::OS::cygwin 0.804; +package IO::Async::OS::cygwin 0.805; use v5.14; use warnings; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/OS/linux.pm new/IO-Async-0.805/lib/IO/Async/OS/linux.pm --- old/IO-Async-0.804/lib/IO/Async/OS/linux.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/OS/linux.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2014-2024 -- [email protected] -package IO::Async::OS::linux 0.804; +package IO::Async::OS::linux 0.805; use v5.14; use warnings; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/OS.pm new/IO-Async-0.805/lib/IO/Async/OS.pm --- old/IO-Async-0.804/lib/IO/Async/OS.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/OS.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2012-2024 -- [email protected] -package IO::Async::OS 0.804; +package IO::Async::OS 0.805; use v5.14; use warnings; @@ -73,6 +73,8 @@ =head1 DESCRIPTION +=for highlighter language=perl + This module acts as a class to provide a number of utility methods whose exact behaviour may depend on the type of OS it is running on. It is provided as a class so that specific kinds of operating system can override methods in it. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/PID.pm new/IO-Async-0.805/lib/IO/Async/PID.pm --- old/IO-Async-0.804/lib/IO/Async/PID.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/PID.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2010-2024 -- [email protected] -package IO::Async::PID 0.804; +package IO::Async::PID 0.805; use v5.14; use warnings; @@ -17,6 +17,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + use IO::Async::PID; use POSIX qw( WEXITSTATUS ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Process.pm new/IO-Async-0.805/lib/IO/Async/Process.pm --- old/IO-Async-0.804/lib/IO/Async/Process.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Process.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2011-2024 -- [email protected] -package IO::Async::Process 0.804; +package IO::Async::Process 0.805; use v5.14; use warnings; @@ -23,6 +23,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + use IO::Async::Process; use IO::Async::Loop; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Protocol/LineStream.pm new/IO-Async-0.805/lib/IO/Async/Protocol/LineStream.pm --- old/IO-Async-0.804/lib/IO/Async/Protocol/LineStream.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Protocol/LineStream.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2010-2024 -- [email protected] -package IO::Async::Protocol::LineStream 0.804; +package IO::Async::Protocol::LineStream 0.805; use v5.14; use warnings; @@ -19,6 +19,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + Most likely this class will be subclassed to implement a particular network protocol. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Protocol/Stream.pm new/IO-Async-0.805/lib/IO/Async/Protocol/Stream.pm --- old/IO-Async-0.804/lib/IO/Async/Protocol/Stream.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Protocol/Stream.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2010-2024 -- [email protected] -package IO::Async::Protocol::Stream 0.804; +package IO::Async::Protocol::Stream 0.805; use v5.14; use warnings; @@ -18,6 +18,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + Most likely this class will be subclassed to implement a particular network protocol. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Protocol.pm new/IO-Async-0.805/lib/IO/Async/Protocol.pm --- old/IO-Async-0.804/lib/IO/Async/Protocol.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Protocol.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2011-2024 -- [email protected] -package IO::Async::Protocol 0.804; +package IO::Async::Protocol 0.805; use v5.14; use warnings; @@ -18,6 +18,8 @@ =head1 DESCRIPTION +=for highlighter language=perl + This subclass of L<IO::Async:Notifier> provides storage for a L<IO::Async::Handle> object, to act as a transport for some protocol. It contains an instance of the transport object, which it adds as a child diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Resolver.pm new/IO-Async-0.805/lib/IO/Async/Resolver.pm --- old/IO-Async-0.804/lib/IO/Async/Resolver.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Resolver.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2007-2024 -- [email protected] -package IO::Async::Resolver 0.804; +package IO::Async::Resolver 0.805; use v5.14; use warnings; @@ -37,6 +37,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + This object is used indirectly via an L<IO::Async::Loop>: use Future::AsyncAwait; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Routine.pm new/IO-Async-0.805/lib/IO/Async/Routine.pm --- old/IO-Async-0.804/lib/IO/Async/Routine.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Routine.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2012-2024 -- [email protected] -package IO::Async::Routine 0.804; +package IO::Async::Routine 0.805; use v5.14; use warnings; @@ -23,6 +23,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + use IO::Async::Routine; use IO::Async::Channel; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Signal.pm new/IO-Async-0.805/lib/IO/Async/Signal.pm --- old/IO-Async-0.804/lib/IO/Async/Signal.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Signal.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2009-2024 -- [email protected] -package IO::Async::Signal 0.804; +package IO::Async::Signal 0.805; use v5.14; use warnings; @@ -17,6 +17,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + use IO::Async::Signal; use IO::Async::Loop; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Socket.pm new/IO-Async-0.805/lib/IO/Async/Socket.pm --- old/IO-Async-0.804/lib/IO/Async/Socket.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Socket.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2011-2024 -- [email protected] -package IO::Async::Socket 0.804; +package IO::Async::Socket 0.805; use v5.14; use warnings; @@ -21,6 +21,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + use Future::AsyncAwait; use IO::Async::Socket; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Stream.pm new/IO-Async-0.805/lib/IO/Async/Stream.pm --- old/IO-Async-0.804/lib/IO/Async/Stream.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Stream.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2006-2024 -- [email protected] -package IO::Async::Stream 0.804; +package IO::Async::Stream 0.805; use v5.14; use warnings; @@ -50,6 +50,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + use IO::Async::Stream; use IO::Async::Loop; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Test.pm new/IO-Async-0.805/lib/IO/Async/Test.pm --- old/IO-Async-0.804/lib/IO/Async/Test.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Test.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2007-2024 -- [email protected] -package IO::Async::Test 0.804; +package IO::Async::Test 0.805; use v5.14; use warnings; @@ -22,6 +22,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + use Test2::V0; use Future::AsyncAwait; use IO::Async::Test; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Timer/Absolute.pm new/IO-Async-0.805/lib/IO/Async/Timer/Absolute.pm --- old/IO-Async-0.804/lib/IO/Async/Timer/Absolute.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Timer/Absolute.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2010-2024 -- [email protected] -package IO::Async::Timer::Absolute 0.804; +package IO::Async::Timer::Absolute 0.805; use v5.14; use warnings; @@ -17,6 +17,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + use IO::Async::Timer::Absolute; use POSIX qw( mktime ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Timer/Countdown.pm new/IO-Async-0.805/lib/IO/Async/Timer/Countdown.pm --- old/IO-Async-0.804/lib/IO/Async/Timer/Countdown.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Timer/Countdown.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2009-2012 -- [email protected] -package IO::Async::Timer::Countdown 0.804; +package IO::Async::Timer::Countdown 0.805; use v5.14; use warnings; @@ -17,6 +17,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + use IO::Async::Timer::Countdown; use IO::Async::Loop; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Timer/Periodic.pm new/IO-Async-0.805/lib/IO/Async/Timer/Periodic.pm --- old/IO-Async-0.804/lib/IO/Async/Timer/Periodic.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Timer/Periodic.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2009-2024 -- [email protected] -package IO::Async::Timer::Periodic 0.804; +package IO::Async::Timer::Periodic 0.805; use v5.14; use warnings; @@ -17,6 +17,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + use IO::Async::Timer::Periodic; use IO::Async::Loop; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async/Timer.pm new/IO-Async-0.805/lib/IO/Async/Timer.pm --- old/IO-Async-0.804/lib/IO/Async/Timer.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async/Timer.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2009-2024 -- [email protected] -package IO::Async::Timer 0.804; +package IO::Async::Timer 0.805; use v5.14; use warnings; @@ -17,6 +17,8 @@ =head1 DESCRIPTION +=for highlighter language=perl + This module provides a subclass of L<IO::Async::Notifier> for implementing notifiers that use timed delays. For specific implementations, see one of the subclasses: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/lib/IO/Async.pm new/IO-Async-0.805/lib/IO/Async.pm --- old/IO-Async-0.804/lib/IO/Async.pm 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/lib/IO/Async.pm 2026-01-19 16:19:46.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2008-2024 -- [email protected] -package IO::Async 0.804; +package IO::Async 0.805; use v5.14; use warnings; @@ -18,6 +18,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + use IO::Async::Stream; use IO::Async::Loop; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/t/27file.t new/IO-Async-0.805/t/27file.t --- old/IO-Async-0.804/t/27file.t 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/t/27file.t 2026-01-19 16:19:46.000000000 +0100 @@ -106,6 +106,22 @@ is( $new_stat->dev, (stat $wr)[0], '$new_stat->dev for renamed file' ); is( $new_stat->ino, (stat $wr)[1], '$new_stat->ino for renamed file' ); + undef $devino_changed; + unlink $filename; + + wait_for { $devino_changed }; + + ok( defined $old_stat, '$old_stat was defined for removed file' ); + ok( !defined $new_stat, '$new_stat now undef for removed file' ); + + undef $devino_changed; + { open my $tmp, ">", $filename or die "Cannot create $filename - $!"; } + + wait_for { $devino_changed }; + + ok( !defined $old_stat, '$old_stat was undef for created file' ); + ok( defined $new_stat, '$new_stat now defined for created file' ); + $loop->remove( $file ); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/IO-Async-0.804/t/70future-io.t new/IO-Async-0.805/t/70future-io.t --- old/IO-Async-0.804/t/70future-io.t 2025-04-22 18:38:04.000000000 +0200 +++ new/IO-Async-0.805/t/70future-io.t 2026-01-19 16:19:46.000000000 +0100 @@ -6,7 +6,7 @@ use IO::Async::Test; use Test2::V0; -use Test::Future::IO::Impl; +use Test::Future::IO::Impl 0.17; use lib "."; use t::TimeAbout; @@ -16,8 +16,9 @@ use Errno; -eval { require Future::IO; require Future::IO::ImplBase } or - plan skip_all => "Future::IO is not available"; +eval { require Future::IO; Future::IO->VERSION( '0.19' ); + require Future::IO::ImplBase } or + plan skip_all => "Future::IO 0.19 is not available"; require Future::IO::Impl::IOAsync; use constant AUT => $ENV{TEST_QUICK_TIMERS} ? 0.1 : 1; @@ -64,6 +65,13 @@ is( $buf, "ABCD", 'Future::IO->syswrite wrote data' ); } -run_tests qw( sleep sysread syswrite waitpid ); +run_tests qw( + sleep + poll_no_hup + read sysread write syswrite + connect accept + send recv + waitpid +); done_testing; ++++++ README.md ++++++ ## Build Results Current state of perl in openSUSE:Factory is  The current state of perl in the devel project build (devel:languages:perl)  ++++++ _scmsync.obsinfo ++++++ mtime: 1768974526 commit: b5cd5f91ffc19e09ce141189565e613b630e9d362a2d39c323b92c5e95df025a url: https://src.opensuse.org/perl/perl-IO-Async revision: b5cd5f91ffc19e09ce141189565e613b630e9d362a2d39c323b92c5e95df025a projectscmsync: https://src.opensuse.org/perl/_ObsPrj ++++++ build.specials.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/.gitignore new/.gitignore --- old/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/.gitignore 2026-01-21 06:48:46.000000000 +0100 @@ -0,0 +1 @@ +.osc
