--- Coro/Coro.pm 2006/11/24 13:40:36 1.82 +++ Coro/Coro.pm 2006/11/27 02:01:33 1.89 @@ -37,13 +37,13 @@ use Coro::State; -use base Exporter::; +use base qw(Coro::State Exporter); -our $idle; # idle coroutine +our $idle; # idle handler our $main; # main coroutine our $current; # current coroutine -our $VERSION = '2.5'; +our $VERSION = '3.0'; our @EXPORT = qw(async cede schedule terminate current); our %EXPORT_TAGS = ( @@ -97,7 +97,12 @@ =item $current (or as function: current) -The current coroutine (the last coroutine switched to). The initial value is C<$main> (of course). +The current coroutine (the last coroutine switched to). The initial value +is C<$main> (of course). + +This variable is B I. It is provided for performance +reasons. If performance is not essentiel you are encouraged to use the +C function instead. =cut @@ -112,22 +117,25 @@ =item $idle -The coroutine to switch to when no other coroutine is running. The default -implementation prints "FATAL: deadlock detected" and exits. +A callback that is called whenever the scheduler finds no ready coroutines +to run. The default implementation prints "FATAL: deadlock detected" and +exits. + +This hook is overwritten by modules such as C and +C to wait on an external event that hopefully wakes up some +coroutine. =cut -# should be done using priorities :( -$idle = new Coro sub { +$idle = sub { print STDERR "FATAL: deadlock detected\n"; - exit(51); + exit (51); }; # this coroutine is necessary because a coroutine # cannot destroy itself. my @destroy; -my $manager; -$manager = new Coro sub { +my $manager; $manager = new Coro sub { while () { # by overwriting the state object with the manager we destroy it # while still being able to schedule this coroutine (in case it has @@ -139,11 +147,11 @@ $coro->{status} ||= []; $_->ready for @{delete $coro->{join} || []}; - # the next line destroys the _coro_state, but keeps the + # the next line destroys the coro state, but keeps the # process itself intact (we basically make it a zombie # process that always runs the manager thread, so it's possible # to transfer() to this process). - $coro->{_coro_state}->_clone_state_from ($manager->{_coro_state}); + $coro->_clone_state_from ($manager); } &schedule; } @@ -165,6 +173,8 @@ (usually unused). When the sub returns the new process is automatically terminated. +Calling C in a coroutine will not work correctly, so do not do that. + When the coroutine dies, the program will exit, just as in the main program. @@ -177,9 +187,8 @@ sub async(&@) { my $pid = new Coro @_; - $manager->ready; # this ensures that the stack is cloned from the manager $pid->ready; - $pid; + $pid } =item schedule @@ -225,17 +234,18 @@ called. To make the process run you must first put it into the ready queue by calling the ready method. +Calling C in a coroutine will not work correctly, so do not do that. + =cut -sub _newcoro { +sub _new_coro { terminate &{+shift}; } sub new { my $class = shift; - bless { - _coro_state => (new Coro::State \&_newcoro, @_), - }, $class; + + $class->SUPER::new (\&_new_coro, @_) } =item $process->ready @@ -298,23 +308,11 @@ running) will only take effect after the next schedule (of that process). This is a bug that will be fixed in some future version. -=cut - -sub prio { - shift->{_coro_state}->prio (@_) -} - =item $newprio = $process->nice ($change) Similar to C, but subtract the given value from the priority (i.e. higher values mean lower priority, just as in unix). -=cut - -sub nice { - shift->{_coro_state}->nice (@_) -} - =item $olddesc = $process->desc ($newdesc) Sets (or gets in case the argument is missing) the description for this