From: Marc Lehmann To: "Eric G. Bergeron" Subject: Re: About the Coro module > I am starting to use your perl Coro module and I think that I noticed a Well, perl is not really coro-safe, or was it that coro is not perl-safe? :) It should work, but some corner cases, especially at global destruction, are not handled as nice as they could. > bug (I just don't know where the bug is.). This code below seems to run the > function 1 time too many. > > use Coro; > use strict; > my $proc=new Coro sub > { my $i=0; > while (1) > { print "$i "; $i++; > cede; > } > }; > $proc->ready(); > cede; > $proc->ready(); > cede; no, that's correct. "cede" is like the posix "yield" function. It doesn't take the process out of the ready queue, it just gives other processes the opportunity to run. So a single ->ready suffices to make it run as often as it wants - until the main program exits, that is. The second ->ready call is actually a bug (not fatal), as it puts the process a second time into the run queue. This is not a problem for Coro, but not expected by you :) If you want to switch to another coro _without_ being put into the ready queue automatically, don't use "cede" but "schedule". Schedule just switches to another process and leaves the current one alone, while cede is just a temporary switch - it will return later. Think of coros as processes. The Coro::State and Coro::Cont modules implement different ideas, so you could roll your own stuff if you really wanted to. A simple (althogh difficult to read) example is in one of the many semaphore modules (e.g. Coro::Signal). The wait method for example: sub wait { if ($_[0][0]) { $_[0][0] = 0; } else { push @{$_[0][1]}, $Coro::current; # <- here Coro::schedule; # <- here } } It first remembers the "current" process (the calling coro) internally and then calls schedule, which cuases the process to stop running immediately. Unless somebody else wakes it up it'll never run again. "send" does this: sub send { if (@{$_[0][1]}) { (shift @{$_[0][1]})->ready; # <- here } else { $_[0][0] = 1; } } It puts the waiting process into the ready queue again. "cede" is implemented like this (in C, but the basic idea is the same): sub cede { $current->ready; schedule; } so it put's itself into the ready queue and calls the scheduler. -- -----==- | ----==-- _ | ---==---(_)__ __ ____ __ Marc Lehmann +-- --==---/ / _ \/ // /\ \/ / schmorp@schmorp.de |e| -=====/_/_//_/\_,_/ /_/\_\ XX11-RIPE --+ The choice of a GNU generation | |