--- cvsroot/Coro/Coro.pm 2009/03/16 22:22:12 1.251 +++ cvsroot/Coro/Coro.pm 2009/08/13 02:35:41 1.264 @@ -82,7 +82,7 @@ our $main; # main coro our $current; # current coro -our $VERSION = 5.131; +our $VERSION = 5.162; our @EXPORT = qw(async async_pool cede schedule terminate current unblock_sub); our %EXPORT_TAGS = ( @@ -209,14 +209,6 @@ print "@_\n"; } 1,2,3,4; -=cut - -sub async(&@) { - my $coro = new Coro @_; - $coro->ready; - $coro -} - =item async_pool { ... } [@args...] Similar to C, but uses a coro pool, so you should not call @@ -340,15 +332,15 @@ does, and are useful when you want to localise some resource to a specific coro. -They slow down coro switching considerably for coros that use -them (But coro switching is still reasonably fast if the handlers are -fast). +They slow down thread switching considerably for coros that use them +(about 40% for a BLOCK with a single assignment, so thread switching is +still reasonably fast if the handlers are fast). These functions are best understood by an example: The following function will change the current timezone to "Antarctica/South_Pole", which requires a call to C, but by using C and C, which remember/change the current timezone and restore the previous -value, respectively, the timezone is only changes for the coro that +value, respectively, the timezone is only changed for the coro that installed those handlers. use POSIX qw(tzset); @@ -376,6 +368,36 @@ working directory etc.) to a block, despite the existance of other coros. +Another interesting example implements time-sliced multitasking using +interval timers (this could obviously be optimised, but does the job): + + # "timeslice" the given block + sub timeslice(&) { + use Time::HiRes (); + + Coro::on_enter { + # on entering the thread, we set an VTALRM handler to cede + $SIG{VTALRM} = sub { cede }; + # and then start the interval timer + Time::HiRes::setitimer &Time::HiRes::ITIMER_VIRTUAL, 0.01, 0.01; + }; + Coro::on_leave { + # on leaving the thread, we stop the interval timer again + Time::HiRes::setitimer &Time::HiRes::ITIMER_VIRTUAL, 0, 0; + }; + + &{+shift}; + } + + # use like this: + timeslice { + # The following is an endless loop that would normally + # monopolise the process. Since it runs in a timesliced + # environment, it will regularly cede to other threads. + while () { } + }; + + =item killall Kills/terminates/cancels all coros except the currently running one. @@ -723,7 +745,9 @@ As soon as the callback is invoked (or when the callback was invoked before C), it will return the arguments originally passed to -the rouse callback. +the rouse callback. In scalar context, that means you get the I +argument, just as if C had a C +statement at the end. See the section B for an actual usage example.