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

Comparing Coro/Coro.pm (file contents):
Revision 1.8 by root, Sat Jul 14 22:14:21 2001 UTC vs.
Revision 1.14 by root, Tue Jul 17 02:21:56 2001 UTC

18 18
19 yield; 19 yield;
20 20
21=head1 DESCRIPTION 21=head1 DESCRIPTION
22 22
23This module collection manages coroutines. Coroutines are similar to
24Threads but don't run in parallel.
25
26This module is still experimental, see the BUGS section below.
27
23=cut 28=cut
24 29
25package Coro; 30package Coro;
26 31
27use Coro::State; 32use Coro::State;
28 33
29use base Exporter; 34use base Exporter;
30 35
31$VERSION = 0.03; 36$VERSION = 0.05;
32 37
33@EXPORT = qw(async yield schedule); 38@EXPORT = qw(async yield schedule terminate);
34@EXPORT_OK = qw($current); 39@EXPORT_OK = qw($current);
35 40
36{ 41{
37 use subs 'async'; 42 use subs 'async';
38 43
59 sub INIT { 64 sub INIT {
60 async pop @async while @async; 65 async pop @async while @async;
61 } 66 }
62} 67}
63 68
64my $idle = new Coro sub {
65 &yield while 1;
66};
67
68=item $main 69=item $main
69 70
70This coroutine represents the main program. 71This coroutine represents the main program.
71 72
72=cut 73=cut
73 74
74$main = new Coro; 75our $main = new Coro;
75 76
76=item $current 77=item $current
77 78
78The current coroutine (the last coroutine switched to). The initial value is C<$main> (of course). 79The current coroutine (the last coroutine switched to). The initial value is C<$main> (of course).
79 80
82# maybe some other module used Coro::Specific before... 83# maybe some other module used Coro::Specific before...
83if ($current) { 84if ($current) {
84 $main->{specific} = $current->{specific}; 85 $main->{specific} = $current->{specific};
85} 86}
86 87
87$current = $main; 88our $current = $main;
89
90=item $idle
91
92The coroutine to switch to when no other coroutine is running. The default
93implementation prints "FATAL: deadlock detected" and exits.
94
95=cut
96
97# should be done using priorities :(
98our $idle = new Coro sub {
99 print STDERR "FATAL: deadlock detected\n";
100 exit(51);
101};
88 102
89# we really need priorities... 103# we really need priorities...
104## my @ready; #d#
90my @ready = (); # the ready queue. hehe, rather broken ;) 105our @ready = (); # the ready queue. hehe, rather broken ;)
91 106
92# static methods. not really. 107# static methods. not really.
93 108
94=head2 STATIC METHODS 109=head2 STATIC METHODS
95 110
96Static methods are actually functions that operate on the current process only. 111Static methods are actually functions that operate on the current process only.
97 112
98=over 4 113=over 4
99 114
100=item async { ... }; 115=item async { ... } [@args...]
101 116
102Create a new asynchronous process and return it's process object 117Create a new asynchronous process and return it's process object
103(usually unused). When the sub returns the new process is automatically 118(usually unused). When the sub returns the new process is automatically
104terminated. 119terminated.
105 120
106=cut 121 # create a new coroutine that just prints its arguments
122 async {
123 print "@_\n";
124 } 1,2,3,4;
107 125
126The coderef you submit MUST NOT be a closure that refers to variables
127in an outer scope. This does NOT work. Pass arguments into it instead.
128
129=cut
130
108sub async(&) { 131sub async(&@) {
109 (new Coro $_[0])->ready; 132 my $pid = new Coro @_;
133 $pid->ready;
134 $pid;
110} 135}
111 136
112=item schedule 137=item schedule
113 138
114Calls the scheduler. Please note that the current process will not be put 139Calls the scheduler. Please note that the current process will not be put
118=cut 143=cut
119 144
120my $prev; 145my $prev;
121 146
122sub schedule { 147sub schedule {
148 # should be done using priorities :(
123 ($prev, $current) = ($current, shift @ready); 149 ($prev, $current) = ($current, shift @ready || $idle);
124 Coro::State::transfer($prev, $current); 150 Coro::State::transfer($prev, $current);
125} 151}
126 152
127=item yield 153=item yield
128 154
138 164
139=item terminate 165=item terminate
140 166
141Terminates the current process. 167Terminates the current process.
142 168
169Future versions of this function will allow result arguments.
170
143=cut 171=cut
144 172
145sub terminate { 173sub terminate {
174 $current->{_results} = [@_];
146 &schedule; 175 &schedule;
147} 176}
148 177
149=back 178=back
150 179
154 183
155These are the methods you can call on process objects. 184These are the methods you can call on process objects.
156 185
157=over 4 186=over 4
158 187
159=item new Coro \&sub; 188=item new Coro \&sub [, @args...]
160 189
161Create a new process and return it. When the sub returns the process 190Create a new process and return it. When the sub returns the process
162automatically terminates. To start the process you must first put it into 191automatically terminates. To start the process you must first put it into
163the ready queue by calling the ready method. 192the ready queue by calling the ready method.
164 193
194The coderef you submit MUST NOT be a closure that refers to variables
195in an outer scope. This does NOT work. Pass arguments into it instead.
196
165=cut 197=cut
198
199sub _newcoro {
200 terminate &{+shift};
201}
166 202
167sub new { 203sub new {
168 my $class = shift; 204 my $class = shift;
169 my $proc = $_[0];
170 bless { 205 bless {
171 _coro_state => new Coro::State ($proc ? sub { &$proc; &terminate } : $proc), 206 _coro_state => (new Coro::State $_[0] && \&_newcoro, @_),
172 }, $class; 207 }, $class;
173} 208}
174 209
175=item $process->ready 210=item $process->ready
176 211
186 221
187=cut 222=cut
188 223
1891; 2241;
190 225
226=head1 BUGS
227
228 - could be faster, especially when the core would introduce special
229 support for coroutines (like it does for threads).
230 - there is still a memleak on coroutine termination that I could not
231 identify. Could be as small as a single SV.
232 - this module is not well-tested.
233
234=head1 SEE ALSO
235
236L<Coro::Channel>, L<Coro::Cont>, L<Coro::Specific>, L<Coro::Semaphore>,
237L<Coro::Signal>, L<Coro::State>, L<Coro::Event>.
238
191=head1 AUTHOR 239=head1 AUTHOR
192 240
193 Marc Lehmann <pcg@goof.com> 241 Marc Lehmann <pcg@goof.com>
194 http://www.goof.com/pcg/marc/ 242 http://www.goof.com/pcg/marc/
195 243

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines