Future-Uring

 view release on metacpan or  search on metacpan

lib/Future/Uring.pm  view on Meta::CPAN


my %events = (
	exited    => WEXITED,
	stopped   => WSTOPPED,
	continued => WCONTINUED,
);

sub waitid($type_name, $id, %args) {
	my $future = Future::Uring::_Future->new;
	my (undef, $sourcename, $line) = caller;
	my $type = $types{$type_name} // croak "Unknown wait type $type_name";
	my $info = Signal::Info->new;
	my $s_flags = to_sflags(\%args);
	my $event = defined $args{event} ? $events{$args{event}} // croak("No such event $args{event}") : WEXITED;
	$event |= WNOWAIT if $args{nowait};
	$id = $id->fileno if $type_name eq 'pidfd' && Scalar::Util::blessed($id) && $id->isa('Linux::FD::Pid');
	my $ring = ring;
	$ring->submit if $args{timeout} && $ring->sq_space_left < 2;

	my $ident = $ring->waitid($type, $id, $info, $event, 0, $s_flags, sub($res, $flags) {
		if ($res >= 0) {
			$future->done($info);
		} else {
			$future->fail(Future::Uring::Exception->new('waitid', $res, $sourcename, $line));
		}
	});

	$future->on_cancel(sub { $ring->cancel($ident, 0, 0) }) if $args{mutable};
	add_timeout($ring, \%args) if $args{timeout};
	return $future;
}

sub waitpid($pid, %args) {
	my $first = waitid('pid', $pid, %args);
	return $first->then(sub($info) {
		my $second = Future->new;
		my $status = $info->code == CLD_EXITED ? ($info->status << 8) :
			$info->code == CLD_DUMPED ? $info->status | 128 : $info->status;
		$second->done($status);
	});
}

# ABSTRACT: Future-returning io_uring functions

package
	Future::Uring::_Future;

use parent 'Future';

sub await($self) {
	my $ring = Future::Uring::ring;
	$ring->run_once until $self->is_ready;
	return $self;
}

package
	Future::Uring::_TimeoutFuture;

use parent -norequire, 'Future::Uring::_Future';

sub update($original, $seconds, %args) {
	my $future = Future::Uring::_Future->new;
	my (undef, $sourcename, $line) = caller;
	my $id = $original->udata('uring_id');

	my $time_spec = ref $seconds ? $seconds : Time::Spec->new($seconds);
	my $flags = $args{flags} // 0;
	my $s_flags = to_sflags(\%args);
	my $ring = Future::Uring::ring();
	$ring->submit if $args{timeout} && $ring->sq_space_left < 2;
	$ring->timeout_update($time_spec, $id, $flags, $s_flags, sub($res, $flags) {
		if ($res < 0) {
			$future->fail(Future::Uring::Exception->new('timeout_update', $res, $sourcename, $line));
		} else {
			$future->done;
		}
		$time_spec;
	});
	$future->on_cancel(sub { $ring->cancel($id, 0, 0) }) if $args{mutable};
	add_timeout($ring, \%args) if $args{timeout};
	return $future;
}


1;

# ABSTRACT: Future returning uring methods

__END__

=pod

=encoding UTF-8

=head1 NAME

Future::Uring - Future-returning io_uring functions

=head1 VERSION

version 0.004

=head1 SYNOPSIS

 use Future::Uring;
 use Future::AsyncAwait;

 my $handle = await Future::Uring::open("input.txt");
 my $result = await $handle->write($buffer);

=head1 DESCRIPTION

B<NOTE: This module is an early/experimental release, API stability is not guaranteed yet>.

This module is an end-user friendly wrapper around Linux' C<io_uring> mechanism. Uring is based on two sets of ring buffers, the submission queue and the completion queue. For every I/O request you need to make (like to read a file, write a file, acc...

All IO functions take the following optional named parameters (many take additional ones):

=over 4

=item * async



( run in 2.133 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )