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

Comparing Coro/Coro.pm (file contents):
Revision 1.134 by root, Sat Sep 22 14:42:56 2007 UTC vs.
Revision 1.142 by root, Tue Oct 2 23:16:24 2007 UTC

50 50
51our $idle; # idle handler 51our $idle; # idle handler
52our $main; # main coroutine 52our $main; # main coroutine
53our $current; # current coroutine 53our $current; # current coroutine
54 54
55our $VERSION = '3.7'; 55our $VERSION = '3.8';
56 56
57our @EXPORT = qw(async async_pool cede schedule terminate current unblock_sub); 57our @EXPORT = qw(async async_pool cede schedule terminate current unblock_sub);
58our %EXPORT_TAGS = ( 58our %EXPORT_TAGS = (
59 prio => [qw(PRIO_MAX PRIO_HIGH PRIO_NORMAL PRIO_LOW PRIO_IDLE PRIO_MIN)], 59 prio => [qw(PRIO_MAX PRIO_HIGH PRIO_NORMAL PRIO_LOW PRIO_IDLE PRIO_MIN)],
60); 60);
116=cut 116=cut
117 117
118$main->{desc} = "[main::]"; 118$main->{desc} = "[main::]";
119 119
120# maybe some other module used Coro::Specific before... 120# maybe some other module used Coro::Specific before...
121$main->{specific} = $current->{specific} 121$main->{_specific} = $current->{_specific}
122 if $current; 122 if $current;
123 123
124_set_current $main; 124_set_current $main;
125 125
126sub current() { $current } 126sub current() { $current }
151 # free coroutine data and mark as destructed 151 # free coroutine data and mark as destructed
152 $self->_destroy 152 $self->_destroy
153 or return; 153 or return;
154 154
155 # call all destruction callbacks 155 # call all destruction callbacks
156 $_->(@{$self->{status}}) 156 $_->(@{$self->{_status}})
157 for @{(delete $self->{destroy_cb}) || []}; 157 for @{(delete $self->{_on_destroy}) || []};
158} 158}
159 159
160# this coroutine is necessary because a coroutine 160# this coroutine is necessary because a coroutine
161# cannot destroy itself. 161# cannot destroy itself.
162my @destroy; 162my @destroy;
241 my $cb; 241 my $cb;
242 242
243 while () { 243 while () {
244 eval { 244 eval {
245 while () { 245 while () {
246 $cb = &_pool_1 246 _pool_1 $cb;
247 or return;
248
249 &$cb; 247 &$cb;
250 248 _pool_2 $cb;
251 return if &_pool_2;
252
253 undef $cb;
254 schedule; 249 &schedule;
255 } 250 }
256 }; 251 };
257 252
253 last if $@ eq "\3terminate\2\n";
258 warn $@ if $@; 254 warn $@ if $@;
259 } 255 }
260} 256}
261 257
262sub async_pool(&@) { 258sub async_pool(&@) {
263 # this is also inlined into the unlock_scheduler 259 # this is also inlined into the unlock_scheduler
264 my $coro = (pop @async_pool) || new Coro \&pool_handler;; 260 my $coro = (pop @async_pool) || new Coro \&pool_handler;
265 261
266 $coro->{_invoke} = [@_]; 262 $coro->{_invoke} = [@_];
267 $coro->ready; 263 $coro->ready;
268 264
269 $coro 265 $coro
312 308
313=item terminate [arg...] 309=item terminate [arg...]
314 310
315Terminates the current coroutine with the given status values (see L<cancel>). 311Terminates the current coroutine with the given status values (see L<cancel>).
316 312
313=item killall
314
315Kills/terminates/cancels all coroutines except the currently running
316one. This is useful after a fork, either in the child or the parent, as
317usually only one of them should inherit the running coroutines.
318
317=cut 319=cut
318 320
319sub terminate { 321sub terminate {
320 $current->cancel (@_); 322 $current->cancel (@_);
323}
324
325sub killall {
326 for (Coro::State::list) {
327 $_->cancel
328 if $_ != $current && UNIVERSAL::isa $_, "Coro";
329 }
321} 330}
322 331
323=back 332=back
324 333
325# dynamic methods 334# dynamic methods
369 378
370=cut 379=cut
371 380
372sub cancel { 381sub cancel {
373 my $self = shift; 382 my $self = shift;
374 $self->{status} = [@_]; 383 $self->{_status} = [@_];
375 384
376 if ($current == $self) { 385 if ($current == $self) {
377 push @destroy, $self; 386 push @destroy, $self;
378 $manager->ready; 387 $manager->ready;
379 &schedule while 1; 388 &schedule while 1;
391=cut 400=cut
392 401
393sub join { 402sub join {
394 my $self = shift; 403 my $self = shift;
395 404
396 unless ($self->{status}) { 405 unless ($self->{_status}) {
397 my $current = $current; 406 my $current = $current;
398 407
399 push @{$self->{destroy_cb}}, sub { 408 push @{$self->{_on_destroy}}, sub {
400 $current->ready; 409 $current->ready;
401 undef $current; 410 undef $current;
402 }; 411 };
403 412
404 &schedule while $current; 413 &schedule while $current;
405 } 414 }
406 415
407 wantarray ? @{$self->{status}} : $self->{status}[0]; 416 wantarray ? @{$self->{_status}} : $self->{_status}[0];
408} 417}
409 418
410=item $coroutine->on_destroy (\&cb) 419=item $coroutine->on_destroy (\&cb)
411 420
412Registers a callback that is called when this coroutine gets destroyed, 421Registers a callback that is called when this coroutine gets destroyed,
416=cut 425=cut
417 426
418sub on_destroy { 427sub on_destroy {
419 my ($self, $cb) = @_; 428 my ($self, $cb) = @_;
420 429
421 push @{ $self->{destroy_cb} }, $cb; 430 push @{ $self->{_on_destroy} }, $cb;
422} 431}
423 432
424=item $oldprio = $coroutine->prio ($newprio) 433=item $oldprio = $coroutine->prio ($newprio)
425 434
426Sets (or gets, if the argument is missing) the priority of the 435Sets (or gets, if the argument is missing) the priority of the
450 459
451=item $olddesc = $coroutine->desc ($newdesc) 460=item $olddesc = $coroutine->desc ($newdesc)
452 461
453Sets (or gets in case the argument is missing) the description for this 462Sets (or gets in case the argument is missing) the description for this
454coroutine. This is just a free-form string you can associate with a coroutine. 463coroutine. This is just a free-form string you can associate with a coroutine.
464
465This method simply sets the C<< $coroutine->{desc} >> member to the given string. You
466can modify this member directly if you wish.
455 467
456=cut 468=cut
457 469
458sub desc { 470sub desc {
459 my $old = $_[0]{desc}; 471 my $old = $_[0]{desc};

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines