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.221 by root, Tue Nov 18 05:51:38 2008 UTC vs.
Revision 1.226 by root, Wed Nov 19 16:01:32 2008 UTC

149 for @{ delete $self->{_on_destroy} || [] }; 149 for @{ delete $self->{_on_destroy} || [] };
150} 150}
151 151
152# this coroutine is necessary because a coroutine 152# this coroutine is necessary because a coroutine
153# cannot destroy itself. 153# cannot destroy itself.
154my @destroy; 154our @destroy;
155my $manager; 155our $manager;
156 156
157$manager = new Coro sub { 157$manager = new Coro sub {
158 while () { 158 while () {
159 (shift @destroy)->_cancel 159 (shift @destroy)->_cancel
160 while @destroy; 160 while @destroy;
305>> on that once some event happens, and last you call C<schedule> to put 305>> on that once some event happens, and last you call C<schedule> to put
306yourself to sleep. Note that a lot of things can wake your coroutine up, 306yourself to sleep. Note that a lot of things can wake your coroutine up,
307so you need to check whether the event indeed happened, e.g. by storing the 307so you need to check whether the event indeed happened, e.g. by storing the
308status in a variable. 308status in a variable.
309 309
310The canonical way to wait on external events is this: 310See B<HOW TO WAIT FOR A CALLBACK>, below, for some ways to wait for callbacks.
311
312 {
313 # remember current coroutine
314 my $current = $Coro::current;
315
316 # register a hypothetical event handler
317 on_event_invoke sub {
318 # wake up sleeping coroutine
319 $current->ready;
320 undef $current;
321 };
322
323 # call schedule until event occurred.
324 # in case we are woken up for other reasons
325 # (current still defined), loop.
326 Coro::schedule while $current;
327 }
328 311
329=item cede 312=item cede
330 313
331"Cede" to other coroutines. This function puts the current coroutine into 314"Cede" to other coroutines. This function puts the current coroutine into
332the ready queue and calls C<schedule>, which has the effect of giving 315the ready queue and calls C<schedule>, which has the effect of giving
357program calls this function, there will be some one-time resource leak. 340program calls this function, there will be some one-time resource leak.
358 341
359=cut 342=cut
360 343
361sub terminate { 344sub terminate {
362 $current->cancel (@_); 345 $current->{_status} = [@_];
346 push @destroy, $current;
347 $manager->ready;
348 do { &schedule } while 1;
363} 349}
364 350
365sub killall { 351sub killall {
366 for (Coro::State::list) { 352 for (Coro::State::list) {
367 $_->cancel 353 $_->cancel
388See C<async> and C<Coro::State::new> for additional info about the 374See C<async> and C<Coro::State::new> for additional info about the
389coroutine environment. 375coroutine environment.
390 376
391=cut 377=cut
392 378
393sub _run_coro { 379sub _terminate {
394 terminate &{+shift}; 380 terminate &{+shift};
395}
396
397sub new {
398 my $class = shift;
399
400 $class->SUPER::new (\&_run_coro, @_)
401} 381}
402 382
403=item $success = $coroutine->ready 383=item $success = $coroutine->ready
404 384
405Put the given coroutine into the end of its ready queue (there is one 385Put the given coroutine into the end of its ready queue (there is one
422 402
423=cut 403=cut
424 404
425sub cancel { 405sub cancel {
426 my $self = shift; 406 my $self = shift;
427 $self->{_status} = [@_];
428 407
429 if ($current == $self) { 408 if ($current == $self) {
430 push @destroy, $self; 409 terminate @_;
431 $manager->ready;
432 &schedule while 1;
433 } else { 410 } else {
411 $self->{_status} = [@_];
434 $self->_cancel; 412 $self->_cancel;
435 } 413 }
436} 414}
437 415
438=item $coroutine->throw ([$scalar]) 416=item $coroutine->throw ([$scalar])
439 417
440If C<$throw> is specified and defined, it will be thrown as an exception 418If C<$throw> is specified and defined, it will be thrown as an exception
441inside the coroutine at the next convenient point in time (usually after 419inside the coroutine at the next convenient point in time. Otherwise
442it gains control at the next schedule/transfer/cede). Otherwise clears the
443exception object. 420clears the exception object.
421
422Coro will check for the exception each time a schedule-like-function
423returns, i.e. after each C<schedule>, C<cede>, C<< Coro::Semaphore->down
424>>, C<< Coro::Handle->readable >> and so on. Most of these functions
425detect this case and return early in case an exception is pending.
444 426
445The exception object will be thrown "as is" with the specified scalar in 427The exception object will be thrown "as is" with the specified scalar in
446C<$@>, i.e. if it is a string, no line number or newline will be appended 428C<$@>, i.e. if it is a string, no line number or newline will be appended
447(unlike with C<die>). 429(unlike with C<die>).
448 430
649 unshift @unblock_queue, [$cb, @_]; 631 unshift @unblock_queue, [$cb, @_];
650 $unblock_scheduler->ready; 632 $unblock_scheduler->ready;
651 } 633 }
652} 634}
653 635
636=item $cb = Coro::rouse_cb
637
638Create and return a "rouse callback". That's a code reference that, when
639called, will save its arguments and notify the owner coroutine of the
640callback.
641
642See the next function.
643
644=item @args = Coro::rouse_wait [$cb]
645
646Wait for the specified rouse callback (or the last one tht was created in
647this coroutine).
648
649As soon as the callback is invoked (or when the calback was invoked before
650C<rouse_wait>), it will return a copy of the arguments originally passed
651to the rouse callback.
652
653See the section B<HOW TO WAIT FOR A CALLBACK> for an actual usage example.
654
654=back 655=back
655 656
656=cut 657=cut
657 658
6581; 6591;
660
661=head1 HOW TO WAIT FOR A CALLBACK
662
663It is very common for a coroutine to wait for some callback to be
664called. This occurs naturally when you use coroutines in an otherwise
665event-based program, or when you use event-based libraries.
666
667These typically register a callback for some event, and call that callback
668when the event occured. In a coroutine, however, you typically want to
669just wait for the event, simplyifying things.
670
671For example C<< AnyEvent->child >> registers a callback to be called when
672a specific child has exited:
673
674 my $child_watcher = AnyEvent->child (pid => $pid, cb => sub { ... });
675
676But from withina coroutine, you often just want to write this:
677
678 my $status = wait_for_child $pid;
679
680Coro offers two functions specifically designed to make this easy,
681C<Coro::rouse_cb> and C<Coro::rouse_wait>.
682
683The first function, C<rouse_cb>, generates and returns a callback that,
684when invoked, will save it's arguments and notify the coroutine that
685created the callback.
686
687The second function, C<rouse_wait>, waits for the callback to be called
688(by calling C<schedule> to go to sleep) and returns the arguments
689originally passed to the callback.
690
691Using these functions, it becomes easy to write the C<wait_for_child>
692function mentioned above:
693
694 sub wait_for_child($) {
695 my ($pid) = @_;
696
697 my $watcher = AnyEvent->child (pid => $pid, cb => Coro::rouse_cb);
698
699 my ($rpid, $rstatus) = Coro::rouse_wait;
700 $rstatus
701 }
702
703In the case where C<rouse_cb> and C<rouse_wait> are not flexible enough,
704you can roll your own, using C<schedule>:
705
706 sub wait_for_child($) {
707 my ($pid) = @_;
708
709 # store the current coroutine in $current,
710 # and provide result variables for the closure passed to ->child
711 my $current = $Coro::current;
712 my ($done, $rstatus);
713
714 # pass a closure to ->child
715 my $watcher = AnyEvent->child (pid => $pid, cb => sub {
716 $rstatus = $_[1]; # remember rstatus
717 $done = 1; # mark $rstatus as valud
718 });
719
720 # wait until the closure has been called
721 schedule while !$done;
722
723 $rstatus
724 }
725
659 726
660=head1 BUGS/LIMITATIONS 727=head1 BUGS/LIMITATIONS
661 728
662=over 4 729=over 4
663 730

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines