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

Comparing Coro/Coro.pm (file contents):
Revision 1.56 by pcg, Sat Nov 15 03:53:10 2003 UTC vs.
Revision 1.65 by root, Tue Feb 22 19:51:58 2005 UTC

38 38
39use vars qw($idle $main $current); 39use vars qw($idle $main $current);
40 40
41use base Exporter; 41use base Exporter;
42 42
43$VERSION = "0.9"; 43$VERSION = 1.1;
44 44
45@EXPORT = qw(async cede schedule terminate current); 45@EXPORT = qw(async cede schedule terminate current);
46%EXPORT_TAGS = ( 46%EXPORT_TAGS = (
47 prio => [qw(PRIO_MAX PRIO_HIGH PRIO_NORMAL PRIO_LOW PRIO_IDLE PRIO_MIN)], 47 prio => [qw(PRIO_MAX PRIO_HIGH PRIO_NORMAL PRIO_LOW PRIO_IDLE PRIO_MIN)],
48); 48);
120# this coroutine is necessary because a coroutine 120# this coroutine is necessary because a coroutine
121# cannot destroy itself. 121# cannot destroy itself.
122my @destroy; 122my @destroy;
123my $manager; 123my $manager;
124$manager = new Coro sub { 124$manager = new Coro sub {
125 while() { 125 while () {
126 # by overwriting the state object with the manager we destroy it 126 # by overwriting the state object with the manager we destroy it
127 # while still being able to schedule this coroutine (in case it has 127 # while still being able to schedule this coroutine (in case it has
128 # been readied multiple times. this is harmless since the manager 128 # been readied multiple times. this is harmless since the manager
129 # can be called as many times as neccessary and will always 129 # can be called as many times as neccessary and will always
130 # remove itself from the runqueue 130 # remove itself from the runqueue
131 while (@destroy) { 131 while (@destroy) {
132 my $coro = pop @destroy; 132 my $coro = pop @destroy;
133 $coro->{status} ||= []; 133 $coro->{status} ||= [];
134 $_->ready for @{delete $coro->{join} || []}; 134 $_->ready for @{delete $coro->{join} || []};
135
136 # the next line destroys the _coro_state, but keeps the
137 # process itself intact (we basically make it a zombie
138 # process that always runs the manager thread, so it's possible
139 # to transfer() to this process).
135 $coro->{_coro_state} = $manager->{_coro_state}; 140 $coro->{_coro_state} = $manager->{_coro_state};
136 } 141 }
137 &schedule; 142 &schedule;
138 } 143 }
139}; 144};
157 # create a new coroutine that just prints its arguments 162 # create a new coroutine that just prints its arguments
158 async { 163 async {
159 print "@_\n"; 164 print "@_\n";
160 } 1,2,3,4; 165 } 1,2,3,4;
161 166
162The coderef you submit MUST NOT be a closure that refers to variables
163in an outer scope. This does NOT work. Pass arguments into it instead.
164
165=cut 167=cut
166 168
167sub async(&@) { 169sub async(&@) {
168 my $pid = new Coro @_; 170 my $pid = new Coro @_;
169 $manager->ready; # this ensures that the stack is cloned from the manager 171 $manager->ready; # this ensures that the stack is cloned from the manager
187 189
188=cut 190=cut
189 191
190=item terminate [arg...] 192=item terminate [arg...]
191 193
192Terminates the current process. 194Terminates the current process with the given status values (see L<cancel>).
193
194Future versions of this function will allow result arguments.
195 195
196=cut 196=cut
197 197
198sub terminate { 198sub terminate {
199 $current->{status} = [@_];
200 $current->cancel; 199 $current->cancel (@_);
201 &schedule;
202 die; # NORETURN
203} 200}
204 201
205=back 202=back
206 203
207# dynamic methods 204# dynamic methods
236 233
237Put the given process into the ready queue. 234Put the given process into the ready queue.
238 235
239=cut 236=cut
240 237
241=item $process->cancel 238=item $process->cancel (arg...)
242 239
243Like C<terminate>, but terminates the specified process instead. 240Temrinates the given process and makes it return the given arguments as
241status (default: the empty list).
244 242
245=cut 243=cut
246 244
247sub cancel { 245sub cancel {
246 my $self = shift;
247 $self->{status} = [@_];
248 push @destroy, $_[0]; 248 push @destroy, $self;
249 $manager->ready; 249 $manager->ready;
250 &schedule if $current == $_[0]; 250 &schedule if $current == $self;
251} 251}
252 252
253=item $process->join 253=item $process->join
254 254
255Wait until the coroutine terminates and return any values given to the 255Wait until the coroutine terminates and return any values given to the
256C<terminate> function. C<join> can be called multiple times from multiple 256C<terminate> or C<cancel> functions. C<join> can be called multiple times
257processes. 257from multiple processes.
258 258
259=cut 259=cut
260 260
261sub join { 261sub join {
262 my $self = shift; 262 my $self = shift;
339 339
340=head1 SEE ALSO 340=head1 SEE ALSO
341 341
342L<Coro::Channel>, L<Coro::Cont>, L<Coro::Specific>, L<Coro::Semaphore>, 342L<Coro::Channel>, L<Coro::Cont>, L<Coro::Specific>, L<Coro::Semaphore>,
343L<Coro::Signal>, L<Coro::State>, L<Coro::Timer>, L<Coro::Event>, 343L<Coro::Signal>, L<Coro::State>, L<Coro::Timer>, L<Coro::Event>,
344L<Coro::L<Coro::RWLock>, Handle>, L<Coro::Socket>. 344L<Coro::Handle>, L<Coro::RWLock>, L<Coro::Socket>.
345 345
346=head1 AUTHOR 346=head1 AUTHOR
347 347
348 Marc Lehmann <pcg@goof.com> 348 Marc Lehmann <pcg@goof.com>
349 http://www.goof.com/pcg/marc/ 349 http://home.schmorp.de/
350 350
351=cut 351=cut
352 352

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines