ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Coro/Coro.pm
(Generate patch)

Comparing cvsroot/Coro/Coro.pm (file contents):
Revision 1.227 by root, Thu Nov 20 03:10:30 2008 UTC vs.
Revision 1.230 by root, Thu Nov 20 07:02:43 2008 UTC

135$idle = sub { 135$idle = sub {
136 require Carp; 136 require Carp;
137 Carp::croak ("FATAL: deadlock detected"); 137 Carp::croak ("FATAL: deadlock detected");
138}; 138};
139 139
140sub _cancel {
141 my ($self) = @_;
142
143 # free coroutine data and mark as destructed
144 $self->_destroy
145 or return;
146
147 # call all destruction callbacks
148 $_->(@{$self->{_status}})
149 for @{ delete $self->{_on_destroy} || [] };
150}
151
152# this coroutine is necessary because a coroutine 140# this coroutine is necessary because a coroutine
153# cannot destroy itself. 141# cannot destroy itself.
154our @destroy; 142our @destroy;
155our $manager; 143our $manager;
156 144
157$manager = new Coro sub { 145$manager = new Coro sub {
158 while () { 146 while () {
159 (shift @destroy)->_cancel 147 Coro::_cancel shift @destroy
160 while @destroy; 148 while @destroy;
161 149
162 &schedule; 150 &schedule;
163 } 151 }
164}; 152};
212Similar to C<async>, but uses a coroutine pool, so you should not call 200Similar to C<async>, but uses a coroutine pool, so you should not call
213terminate or join on it (although you are allowed to), and you get a 201terminate or join on it (although you are allowed to), and you get a
214coroutine that might have executed other code already (which can be good 202coroutine that might have executed other code already (which can be good
215or bad :). 203or bad :).
216 204
217On the plus side, this function is faster than creating (and destroying) 205On the plus side, this function is about twice as fast as creating (and
218a completly new coroutine, so if you need a lot of generic coroutines in 206destroying) a completely new coroutine, so if you need a lot of generic
219quick successsion, use C<async_pool>, not C<async>. 207coroutines in quick successsion, use C<async_pool>, not C<async>.
220 208
221The code block is executed in an C<eval> context and a warning will be 209The code block is executed in an C<eval> context and a warning will be
222issued in case of an exception instead of terminating the program, as 210issued in case of an exception instead of terminating the program, as
223C<async> does. As the coroutine is being reused, stuff like C<on_destroy> 211C<async> does. As the coroutine is being reused, stuff like C<on_destroy>
224will not work in the expected way, unless you call terminate or cancel, 212will not work in the expected way, unless you call terminate or cancel,
319you cannot free all of them, so if a coroutine that is not the main 307you cannot free all of them, so if a coroutine that is not the main
320program calls this function, there will be some one-time resource leak. 308program calls this function, there will be some one-time resource leak.
321 309
322=cut 310=cut
323 311
324sub terminate {
325 $current->{_status} = [@_];
326 push @destroy, $current;
327 $manager->ready;
328 do { &schedule } while 1;
329}
330
331sub killall { 312sub killall {
332 for (Coro::State::list) { 313 for (Coro::State::list) {
333 $_->cancel 314 $_->cancel
334 if $_ != $current && UNIVERSAL::isa $_, "Coro"; 315 if $_ != $current && UNIVERSAL::isa $_, "Coro";
335 } 316 }
390 } else { 371 } else {
391 $self->{_status} = [@_]; 372 $self->{_status} = [@_];
392 $self->_cancel; 373 $self->_cancel;
393 } 374 }
394} 375}
376
377=item $coroutine->schedule_to
378
379Puts the current coroutine to sleep (like C<Coro::schedule>), but instead
380of continuing with the next coro from the ready queue, always switch to
381the given coroutine object (regardless of priority etc.). The readyness
382state of that coroutine isn't changed.
383
384This is an advanced method for special cases - I'd love to hear about any
385uses for this one.
386
387=item $coroutine->cede_to
388
389Like C<schedule_to>, but puts the current coroutine into the ready
390queue. This has the effect of temporarily switching to the given
391coroutine, and continuing some time later.
392
393This is an advanced method for special cases - I'd love to hear about any
394uses for this one.
395 395
396=item $coroutine->throw ([$scalar]) 396=item $coroutine->throw ([$scalar])
397 397
398If C<$throw> is specified and defined, it will be thrown as an exception 398If C<$throw> is specified and defined, it will be thrown as an exception
399inside the coroutine at the next convenient point in time. Otherwise 399inside the coroutine at the next convenient point in time. Otherwise

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines