--- Coro/Coro.pm 2008/11/20 03:14:49 1.228 +++ Coro/Coro.pm 2008/11/21 06:02:07 1.233 @@ -69,7 +69,7 @@ our $main; # main coroutine our $current; # current coroutine -our $VERSION = 5.0; +our $VERSION = "5.0"; our @EXPORT = qw(async async_pool cede schedule terminate current unblock_sub); our %EXPORT_TAGS = ( @@ -137,18 +137,6 @@ Carp::croak ("FATAL: deadlock detected"); }; -sub _cancel { - my ($self) = @_; - - # free coroutine data and mark as destructed - $self->_destroy - or return; - - # call all destruction callbacks - $_->(@{$self->{_status}}) - for @{ delete $self->{_on_destroy} || [] }; -} - # this coroutine is necessary because a coroutine # cannot destroy itself. our @destroy; @@ -156,7 +144,7 @@ $manager = new Coro sub { while () { - (shift @destroy)->_cancel + Coro::_cancel shift @destroy while @destroy; &schedule; @@ -239,13 +227,13 @@ If you are concerned about pooled coroutines growing a lot because a single C used a lot of stackspace you can e.g. C once per second or so to slowly replenish the pool. In -addition to that, when the stacks used by a handler grows larger than 16kb +addition to that, when the stacks used by a handler grows larger than 32kb (adjustable via $Coro::POOL_RSS) it will also be destroyed. =cut our $POOL_SIZE = 8; -our $POOL_RSS = 16 * 1024; +our $POOL_RSS = 32 * 1024; our @async_pool; sub pool_handler { @@ -321,13 +309,6 @@ =cut -sub terminate { - $current->{_status} = [@_]; - push @destroy, $current; - $manager->ready; - do { &schedule } while 1; -} - sub killall { for (Coro::State::list) { $_->cancel @@ -393,6 +374,25 @@ } } +=item $coroutine->schedule_to + +Puts the current coroutine to sleep (like C), but instead +of continuing with the next coro from the ready queue, always switch to +the given coroutine object (regardless of priority etc.). The readyness +state of that coroutine isn't changed. + +This is an advanced method for special cases - I'd love to hear about any +uses for this one. + +=item $coroutine->cede_to + +Like C, but puts the current coroutine into the ready +queue. This has the effect of temporarily switching to the given +coroutine, and continuing some time later. + +This is an advanced method for special cases - I'd love to hear about any +uses for this one. + =item $coroutine->throw ([$scalar]) If C<$throw> is specified and defined, it will be thrown as an exception @@ -500,6 +500,11 @@ $old; } +sub transfer { + require Carp; + Carp::croak ("You must not call ->transfer on Coro objects. Use Coro::State objects or the ->schedule_to method. Caught"); +} + =back =head2 GLOBAL FUNCTIONS