--- Coro/Coro.pm 2008/05/31 12:10:55 1.191 +++ Coro/Coro.pm 2008/11/16 00:55:41 1.219 @@ -18,6 +18,7 @@ cede; # and again # use locking + use Coro::Semaphore; my $lock = new Coro::Semaphore; my $locked; @@ -57,7 +58,7 @@ package Coro; -use strict; +use strict qw(vars subs); no warnings "uninitialized"; use Coro::State; @@ -68,7 +69,7 @@ our $main; # main coroutine our $current; # current coroutine -our $VERSION = 4.742; +our $VERSION = 5.0; our @EXPORT = qw(async async_pool cede schedule terminate current unblock_sub); our %EXPORT_TAGS = ( @@ -83,7 +84,7 @@ This variable stores the coroutine object that represents the main program. While you cna C it and do most other things you can do to coroutines, it is mainly useful to compare again C<$Coro::current>, to see -wether you are running in the main program or not. +whether you are running in the main program or not. =cut @@ -153,7 +154,7 @@ # call all destruction callbacks $_->(@{$self->{_status}}) - for @{(delete $self->{_on_destroy}) || []}; + for @{ delete $self->{_on_destroy} || [] }; } # this coroutine is necessary because a coroutine @@ -169,7 +170,7 @@ &schedule; } }; -$manager->desc ("[coro manager]"); +$manager->{desc} = "[coro manager]"; $manager->prio (PRIO_MAX); =back @@ -222,7 +223,7 @@ or bad :). On the plus side, this function is faster than creating (and destroying) -a completely new coroutine, so if you need a lot of generic coroutines in +a completly new coroutine, so if you need a lot of generic coroutines in quick successsion, use C, not C. The code block is executed in an C context and a warning will be @@ -236,12 +237,12 @@ disabled, the description will be reset and the default output filehandle gets restored, so you can change all these. Otherwise the coroutine will be re-used "as-is": most notably if you change other per-coroutine global -stuff such as C<$/> you I to revert that change, which is most -simply done by using local as in: C< local $/ >. +stuff such as C<$/> you I revert that change, which is most +simply done by using local as in: C<< local $/ >>. -The pool size is limited to C<8> idle coroutines (this can be adjusted by -changing $Coro::POOL_SIZE), and there can be as many non-idle coros as -required. +The idle pool size is limited to C<8> idle coroutines (this can be +adjusted by changing $Coro::POOL_SIZE), but there can be as many non-idle +coros as required. If you are concerned about pooled coroutines growing a lot because a single C used a lot of stackspace you can e.g. C{_invoke} = [@_]; @@ -309,7 +312,7 @@ a variable, then arrange for some callback of yours to call C<< ->ready >> on that once some event happens, and last you call C to put yourself to sleep. Note that a lot of things can wake your coroutine up, -so you need to check wether the event indeed happened, e.g. by storing the +so you need to check whether the event indeed happened, e.g. by storing the status in a variable. The canonical way to wait on external events is this: @@ -358,7 +361,7 @@ usually only one of them should inherit the running coroutines. Note that while this will try to free some of the main programs resources, -you cnanot free all of them, so if a coroutine that is not the main +you cannot free all of them, so if a coroutine that is not the main program calls this function, there will be some one-time resource leak. =cut @@ -417,7 +420,7 @@ =item $is_ready = $coroutine->is_ready -Return wether the coroutine is currently the ready queue or not, +Return whether the coroutine is currently the ready queue or not, =item $coroutine->cancel (arg...) @@ -440,6 +443,25 @@ } } +=item $coroutine->throw ([$scalar]) + +If C<$throw> is specified and defined, it will be thrown as an exception +inside the coroutine at the next convenient point in time (usually after +it gains control at the next schedule/transfer/cede). Otherwise clears the +exception object. + +The exception object will be thrown "as is" with the specified scalar in +C<$@>, i.e. if it is a string, no line number or newline will be appended +(unlike with C). + +This can be used as a softer means than C to ask a coroutine to +end itself, although there is no guarantee that the exception will lead to +termination, and if the exception isn't caught it might well end the whole +program. + +You might also think of C as being the moral equivalent of +Cing a coroutine with a signal (in this case, a scalar). + =item $coroutine->join Wait until the coroutine terminates and return any values given to the @@ -510,26 +532,11 @@ =item $olddesc = $coroutine->desc ($newdesc) Sets (or gets in case the argument is missing) the description for this -coroutine. This is just a free-form string you can associate with a coroutine. - -This method simply sets the C<< $coroutine->{desc} >> member to the given string. You -can modify this member directly if you wish. - -=item $coroutine->throw ([$scalar]) - -If C<$throw> is specified and defined, it will be thrown as an exception -inside the coroutine at the next convinient point in time (usually after -it gains control at the next schedule/transfer/cede). Otherwise clears the -exception object. +coroutine. This is just a free-form string you can associate with a +coroutine. -The exception object will be thrown "as is" with the specified scalar in -C<$@>, i.e. if it is a string, no line number or newline will be appended -(unlike with C). - -This can be used as a softer means than C to ask a coroutine to -end itself, although there is no guarentee that the exception will lead to -termination, and if the exception isn't caught it might well end the whole -program. +This method simply sets the C<< $coroutine->{desc} >> member to the given +string. You can modify this member directly if you wish. =cut @@ -641,7 +648,7 @@ schedule; # sleep well } }; -$unblock_scheduler->desc ("[unblock_sub scheduler]"); +$unblock_scheduler->{desc} = "[unblock_sub scheduler]"; sub unblock_sub(&) { my $cb = shift; @@ -660,11 +667,36 @@ =head1 BUGS/LIMITATIONS +=over 4 + +=item fork with pthread backend + +When Coro is compiled using the pthread backend (which isn't recommended +but required on many BSDs as their libcs are completely broken), then +coroutines will not survive a fork. There is no known workaround except to +fix your libc and use a saner backend. + +=item perl process emulation ("threads") + This module is not perl-pseudo-thread-safe. You should only ever use this module from the same thread (this requirement might be removed in the future to allow per-thread schedulers, but Coro::State does not yet allow -this). I recommend disabling thread support and using processes, as this -is much faster and uses less memory. +this). I recommend disabling thread support and using processes, as having +the windows process emulation enabled under unix roughly halves perl +performance, even when not used. + +=item coroutine switching not signal safe + +You must not switch to another coroutine from within a signal handler +(only relevant with %SIG - most event libraries provide safe signals). + +That means you I call any fucntion that might "block" the +current coroutine - C, C C<< Coro::Semaphore->down >> or +anything that calls those. Everything else, including calling C, +works. + +=back + =head1 SEE ALSO