--- Coro/Coro.pm 2007/01/05 17:44:17 1.106 +++ Coro/Coro.pm 2007/09/19 21:39:15 1.128 @@ -22,8 +22,8 @@ This module collection manages coroutines. Coroutines are similar to threads but don't run in parallel at the same time even on SMP -machines. The specific flavor of coroutine use din this module also -guarentees you that it will not switch between coroutines unless +machines. The specific flavor of coroutine used in this module also +guarantees you that it will not switch between coroutines unless necessary, at easily-identified points in your program, so locking and parallel access are rarely an issue, making coroutine programming much safer than threads programming. @@ -52,7 +52,7 @@ our $main; # main coroutine our $current; # current coroutine -our $VERSION = '3.3'; +our $VERSION = '3.7'; our @EXPORT = qw(async async_pool cede schedule terminate current unblock_sub); our %EXPORT_TAGS = ( @@ -110,7 +110,7 @@ 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 +reasons. If performance is not essential you are encouraged to use the C function instead. =cut @@ -187,10 +187,9 @@ (usually unused). When the sub returns the new coroutine 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. +Calling C in a coroutine will do the same as calling exit outside +the coroutine. Likewise, when the coroutine dies, the program will exit, +just as it would in the main program. # create a new coroutine that just prints its arguments async { @@ -212,7 +211,10 @@ that might have executed other code already (which can be good or bad :). Also, the block is executed in an C context and a warning will be -issued in case of an exception instead of terminating the program, as C does. +issued in case of an exception instead of terminating the program, as +C does. As the coroutine is being reused, stuff like C +will not work in the expected way, unless you call terminate or cancel, +which somehow defeats the purpose of pooling. The priority will be reset to C<0> after each job, otherwise the coroutine will be re-used "as-is". @@ -232,9 +234,8 @@ sub pool_handler { while () { - my ($cb, @arg) = @{ delete $current->{_invoke} }; - eval { + my ($cb, @arg) = @{ delete $current->{_invoke} or return }; $cb->(@arg); }; warn $@ if $@; @@ -242,6 +243,7 @@ last if @pool >= $POOL_SIZE; push @pool, $current; + $current->save (Coro::State::SAVE_DEF); $current->prio (0); schedule; } @@ -249,7 +251,11 @@ sub async_pool(&@) { # this is also inlined into the unlock_scheduler - my $coro = (pop @pool or new Coro \&pool_handler); + my $coro = (pop @pool) || do { + my $coro = new Coro \&pool_handler; + $coro->{desc} = "async_pool"; + $coro + }; $coro->{_invoke} = [@_]; $coro->ready; @@ -277,7 +283,7 @@ undef $current; }; - # call schedule until event occured. + # call schedule until event occurred. # in case we are woken up for other reasons # (current still defined), loop. Coro::schedule while $current; @@ -289,11 +295,15 @@ ready queue and calls C, which has the effect of giving up the current "timeslice" to other coroutines of the same or higher priority. +Returns true if at least one coroutine switch has happened. + =item Coro::cede_notself Works like cede, but is not exported by default and will cede to any coroutine, regardless of priority, once. +Returns true if at least one coroutine switch has happened. + =item terminate [arg...] Terminates the current coroutine with the given status values (see L). @@ -321,7 +331,7 @@ called. To make the coroutine 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. +See C for additional discussion. =cut @@ -454,14 +464,14 @@ =item Coro::nready Returns the number of coroutines that are currently in the ready state, -i.e. that can be swicthed to. The value C<0> means that the only runnable +i.e. that can be switched to. The value C<0> means that the only runnable coroutine is the currently running one, so C would have no effect, and C would cause a deadlock unless there is an idle handler that wakes up some coroutines. =item my $guard = Coro::guard { ... } -This creates and returns a guard object. Nothing happens until the objetc +This creates and returns a guard object. Nothing happens until the object gets destroyed, in which case the codeblock given as argument will be executed. This is useful to free locks or other resources in case of a runtime error or when the coroutine gets canceled, as in both cases the @@ -500,7 +510,7 @@ immediately without blocking, returning nothing, while the original code ref will be called (with parameters) from within its own coroutine. -The reason this fucntion exists is that many event libraries (such as the +The reason this function exists is that many event libraries (such as the venerable L module) are not coroutine-safe (a weaker form of thread-safety). This means you must not block within event callbacks, otherwise you might suffer from crashes or worse. @@ -556,7 +566,7 @@ destruction. very bad things might happen otherwise (usually segfaults). - this module is not thread-safe. You should only ever use this module - from the same thread (this requirement might be losened in the future + from the same thread (this requirement might be loosened in the future to allow per-thread schedulers, but Coro::State does not yet allow this).