--- Coro/Coro.pm 2001/10/09 00:39:08 1.39 +++ Coro/Coro.pm 2001/10/28 17:00:05 1.40 @@ -126,7 +126,12 @@ # been readied multiple times. this is harmless since the manager # can be called as many times as neccessary and will always # remove itself from the runqueue - (pop @destroy)->{_coro_state} = $manager->{_coro_state} while @destroy; + while (@destroy) { + my $coro = pop @destroy; + $coro->{status} ||= []; + $_->ready for @{delete $coro->{join} || []}; + $coro->{_coro_state} = $manager->{_coro_state}; + } &schedule; } }; @@ -178,7 +183,7 @@ =cut -=item terminate +=item terminate [arg...] Terminates the current process. @@ -187,6 +192,7 @@ =cut sub terminate { + $current->{status} = [@_]; $current->cancel; &schedule; die; # NORETURN @@ -205,8 +211,9 @@ =item new Coro \&sub [, @args...] Create a new process and return it. When the sub returns the process -automatically terminates. To start the process you must first put it into -the ready queue by calling the ready method. +automatically terminates as if C with the returned values were +called. To start the process you must first put it into the ready queue by +calling the ready method. The coderef you submit MUST NOT be a closure that refers to variables in an outer scope. This does NOT work. Pass arguments into it instead. @@ -242,6 +249,23 @@ &schedule if $current == $_[0]; } +=item $process->join + +Wait until the coroutine terminates and return any values given to the +C function. C can be called multiple times from multiple +processes. + +=cut + +sub join { + my $self = shift; + unless ($self->{status}) { + push @{$self->{join}}, $current; + &schedule; + } + wantarray ? @{$self->{status}} : $self->{status}[0]; +} + =item $oldprio = $process->prio($newprio) Sets the priority of the process. Higher priority processes get run before