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

Comparing Coro/Coro.pm (file contents):
Revision 1.5 by root, Tue Jul 10 01:43:21 2001 UTC vs.
Revision 1.6 by root, Tue Jul 10 21:19:47 2001 UTC

1=head1 NAME 1=head1 NAME
2 2
3Coro - create and manage coroutines 3Coro - create and manage simple coroutines
4 4
5=head1 SYNOPSIS 5=head1 SYNOPSIS
6 6
7 use Coro; 7 use Coro;
8 8
9 $new = new Coro sub { 9 $new = new Coro sub {
10 print "in coroutine, switching back\n"; 10 print "in coroutine, switching back\n";
11 $Coro::main->resume; 11 $new->transfer($main);
12 print "in coroutine again, switching back\n"; 12 print "in coroutine again, switching back\n";
13 $Coro::main->resume; 13 $new->transfer($main);
14 }; 14 };
15 15
16 $main = new Coro;
17
16 print "in main, switching to coroutine\n"; 18 print "in main, switching to coroutine\n";
17 $new->resume; 19 $main->transfer($new);
18 print "back in main, switch to coroutine again\n"; 20 print "back in main, switch to coroutine again\n";
19 $new->resume; 21 $main->transfer($new);
20 print "back in main\n"; 22 print "back in main\n";
21 23
22=head1 DESCRIPTION 24=head1 DESCRIPTION
23 25
24This module implements coroutines. Coroutines, similar to continuations, 26This module implements coroutines. Coroutines, similar to continuations,
41 43
42 require XSLoader; 44 require XSLoader;
43 XSLoader::load Coro, $VERSION; 45 XSLoader::load Coro, $VERSION;
44} 46}
45 47
46=item $main 48=item $coro = new [$coderef [, @args]]
47 49
48This coroutine represents the main program. 50Create a new coroutine and return it. The first C<transfer> call to this
51coroutine will start execution at the given coderef. If, the subroutine
52returns it will be executed again.
49 53
50=item $current 54If the coderef is omitted this function will create a new "empty"
51 55coroutine, i.e. a coroutine that cannot be transfered to but can be used
52The current coroutine (the last coroutine switched to). The initial value is C<$main> (of course). 56to save the current coroutine in.
53 57
54=cut 58=cut
55 59
56$main = $current = _newprocess { 60sub new {
57 # never being called 61 my $class = $_[0];
58}; 62 my $proc = $_[1] || sub { die "tried to transfer to an empty coroutine" };
63 bless _newprocess {
64 do {
65 eval { &$proc };
66 if ($@) {
67 $error_msg = $@;
68 $error_coro = _newprocess { };
69 &transfer($error_coro, $error);
70 }
71 } while (1);
72 }, $class;
73}
74
75=item $prev->transfer($next)
76
77Save the state of the current subroutine in $prev and switch to the
78coroutine saved in $next.
79
80=cut
81
82# I call the _transfer function from a perl function
83# because that way perl saves all important things on
84# the stack.
85sub transfer {
86 _transfer($_[0], $_[1]);
87}
59 88
60=item $error, $error_msg, $error_coro 89=item $error, $error_msg, $error_coro
61 90
62This coroutine will be called on fatal errors. C<$error_msg> and 91This coroutine will be called on fatal errors. C<$error_msg> and
63C<$error_coro> return the error message and the error-causing coroutine, 92C<$error_coro> return the error message and the error-causing coroutine
64respectively. 93(NOT an object) respectively. This API might change.
65 94
66=cut 95=cut
67 96
68$error_msg = 97$error_msg =
69$error_coro = undef; 98$error_coro = undef;
70 99
71$error = _newprocess { 100$error = _newprocess {
72 print STDERR "FATAL: $error_msg\nprogram aborted\n"; 101 print STDERR "FATAL: $error_msg\nprogram aborted\n";
73 exit 250; 102 exit 50;
74}; 103};
75
76=item $coro = new $coderef [, @args]
77
78Create a new coroutine and return it. The first C<resume> call to this
79coroutine will start execution at the given coderef. If it returns it
80should return a coroutine to switch to. If, after returning, the coroutine
81is C<resume>d again it starts execution again at the givne coderef.
82
83=cut
84
85sub new {
86 my $class = $_[0];
87 my $proc = $_[1];
88 bless _newprocess {
89 do {
90 eval { &$proc->resume };
91 if ($@) {
92 ($error_msg, $error_coro) = ($@, $current);
93 $error->resume;
94 }
95 } while (1);
96 }, $class;
97}
98
99=item $coro->resume
100
101Resume execution at the given coroutine.
102
103=cut
104
105my $prev;
106
107# I call the _transfer function from a pelr function
108# because that way perl saves all important things on
109# the stack.
110sub resume {
111 $prev = $current; $current = $_[0];
112 _transfer($prev, $current);
113}
114 104
1151; 1051;
116 106
117=back 107=back
118 108

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines