Acme-Parataxis
view release on metacpan or search on metacpan
lib/Acme/Parataxis.pm view on Meta::CPAN
return ( ref $rv eq 'ARRAY' ) ? ( wantarray ? @$rv : $rv->[-1] ) : $rv;
}
method transfer (@args) {
croak 'Cannot transfer to a finished fiber' if $self->is_done;
my $rv = Acme::Parataxis::coro_transfer( $fid, \@args );
if ( $self->is_done ) {
my $err = $error;
die $err if defined $err;
}
return unless defined $rv;
return ( ref $rv eq 'ARRAY' ) ? ( wantarray ? @$rv : $rv->[-1] ) : $rv;
}
method is_done () {
return 1 if $is_done;
if ( defined $fid && $fid >= 0 && Acme::Parataxis::is_finished($fid) ) {
$is_done = 1;
my $old_fid = $fid;
$fid = -1;
delete $REGISTRY{$old_fid};
Acme::Parataxis::destroy_coro($old_fid);
return 1;
}
return 0;
}
method wait () {
while ( !$self->is_done ) {
Acme::Parataxis->yield('WAITING_FOR_CHILD');
}
return $self->result;
}
method DESTROY {
return if ${^GLOBAL_PHASE} eq 'DESTRUCT';
if ( defined $fid && $fid >= 0 ) {
delete $REGISTRY{$fid};
Acme::Parataxis::destroy_coro($fid);
$fid = -1;
}
}
sub by_id ( $class, $fid ) { $REGISTRY{$fid} }
}
class #
Acme::Parataxis::Root {
method transfer (@args) {
my $rv = Acme::Parataxis::coro_transfer( -1, \@args );
return unless defined $rv;
return ( ref $rv eq 'ARRAY' ) ? ( wantarray ? @$rv : $rv->[-1] ) : $rv;
}
method fid () {-1}
}
class #
Acme::Parataxis::Future {
use Carp qw[croak];
field $is_ready : reader = 0;
field $result;
field $error;
field @callbacks;
method result () {
croak 'Future not ready' unless $is_ready;
return $result;
}
method set_result ($val) {
die 'Future already ready' if $is_ready;
$result = $val;
$is_ready = 1;
$_->($self) for @callbacks;
}
method set_error ($err) {
die 'Future already ready' if $is_ready;
$error = $err;
$is_ready = 1;
$_->($self) for @callbacks;
}
method clear_result () {
$result = undef;
$error = undef;
}
method on_ready ($cb) {
if ($is_ready) { $cb->($self) }
else { push @callbacks, $cb }
}
method await () {
return $self->result if $is_ready;
my $fid = Acme::Parataxis->current_fid;
$self->on_ready(
sub ($f) {
Acme::Parataxis::_scheduler_enqueue_by_id($fid);
}
);
Acme::Parataxis->yield('WAITING');
$self->result;
}
}
END { cleanup() unless ${^GLOBAL_PHASE} eq 'DESTRUCT' }
}
1;
( run in 0.715 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )