… | |
… | |
2 | |
2 | |
3 | Coro - coroutine process abstraction |
3 | Coro - coroutine process abstraction |
4 | |
4 | |
5 | =head1 SYNOPSIS |
5 | =head1 SYNOPSIS |
6 | |
6 | |
7 | use Coro; |
7 | use Coro; |
8 | |
8 | |
9 | async { |
9 | async { |
10 | # some asynchronous thread of execution |
10 | # some asynchronous thread of execution |
11 | print "2\n"; |
11 | print "2\n"; |
12 | cede; # yield back to main |
12 | cede; # yield back to main |
13 | print "4\n"; |
13 | print "4\n"; |
14 | }; |
14 | }; |
15 | print "1\n"; |
15 | print "1\n"; |
16 | cede; # yield to coroutine |
16 | cede; # yield to coroutine |
17 | print "3\n"; |
17 | print "3\n"; |
18 | cede; # and again |
18 | cede; # and again |
19 | |
19 | |
20 | # use locking |
20 | # use locking |
21 | my $lock = new Coro::Semaphore; |
21 | my $lock = new Coro::Semaphore; |
22 | my $locked; |
22 | my $locked; |
23 | |
23 | |
24 | $lock->down; |
24 | $lock->down; |
25 | $locked = 1; |
25 | $locked = 1; |
26 | $lock->up; |
26 | $lock->up; |
27 | |
27 | |
28 | =head1 DESCRIPTION |
28 | =head1 DESCRIPTION |
29 | |
29 | |
30 | This module collection manages coroutines. Coroutines are similar |
30 | This module collection manages coroutines. Coroutines are similar |
31 | to threads but don't run in parallel at the same time even on SMP |
31 | to threads but don't run in parallel at the same time even on SMP |
… | |
… | |
57 | |
57 | |
58 | our $idle; # idle handler |
58 | our $idle; # idle handler |
59 | our $main; # main coroutine |
59 | our $main; # main coroutine |
60 | our $current; # current coroutine |
60 | our $current; # current coroutine |
61 | |
61 | |
62 | our $VERSION = '4.1'; |
62 | our $VERSION = 4.6; |
63 | |
63 | |
64 | our @EXPORT = qw(async async_pool cede schedule terminate current unblock_sub); |
64 | our @EXPORT = qw(async async_pool cede schedule terminate current unblock_sub); |
65 | our %EXPORT_TAGS = ( |
65 | our %EXPORT_TAGS = ( |
66 | prio => [qw(PRIO_MAX PRIO_HIGH PRIO_NORMAL PRIO_LOW PRIO_IDLE PRIO_MIN)], |
66 | prio => [qw(PRIO_MAX PRIO_HIGH PRIO_NORMAL PRIO_LOW PRIO_IDLE PRIO_MIN)], |
67 | ); |
67 | ); |
68 | our @EXPORT_OK = (@{$EXPORT_TAGS{prio}}, qw(nready)); |
68 | our @EXPORT_OK = (@{$EXPORT_TAGS{prio}}, qw(nready)); |
69 | |
69 | |
70 | { |
|
|
71 | my @async; |
|
|
72 | my $init; |
|
|
73 | |
|
|
74 | # this way of handling attributes simply is NOT scalable ;() |
|
|
75 | sub import { |
|
|
76 | no strict 'refs'; |
|
|
77 | |
|
|
78 | Coro->export_to_level (1, @_); |
|
|
79 | |
|
|
80 | my $old = *{(caller)[0]."::MODIFY_CODE_ATTRIBUTES"}{CODE}; |
|
|
81 | *{(caller)[0]."::MODIFY_CODE_ATTRIBUTES"} = sub { |
|
|
82 | my ($package, $ref) = (shift, shift); |
|
|
83 | my @attrs; |
|
|
84 | for (@_) { |
|
|
85 | if ($_ eq "Coro") { |
|
|
86 | push @async, $ref; |
|
|
87 | unless ($init++) { |
|
|
88 | eval q{ |
|
|
89 | sub INIT { |
|
|
90 | &async(pop @async) while @async; |
|
|
91 | } |
|
|
92 | }; |
|
|
93 | } |
|
|
94 | } else { |
|
|
95 | push @attrs, $_; |
|
|
96 | } |
|
|
97 | } |
|
|
98 | return $old ? $old->($package, $ref, @attrs) : @attrs; |
|
|
99 | }; |
|
|
100 | } |
|
|
101 | |
|
|
102 | } |
|
|
103 | |
|
|
104 | =over 4 |
70 | =over 4 |
105 | |
71 | |
106 | =item $main |
72 | =item $main |
107 | |
73 | |
108 | This coroutine represents the main program. |
74 | This coroutine represents the main program. |
… | |
… | |
177 | &schedule; |
143 | &schedule; |
178 | } |
144 | } |
179 | }; |
145 | }; |
180 | $manager->desc ("[coro manager]"); |
146 | $manager->desc ("[coro manager]"); |
181 | $manager->prio (PRIO_MAX); |
147 | $manager->prio (PRIO_MAX); |
182 | |
|
|
183 | # static methods. not really. |
|
|
184 | |
148 | |
185 | =back |
149 | =back |
186 | |
150 | |
187 | =head2 STATIC METHODS |
151 | =head2 STATIC METHODS |
188 | |
152 | |
… | |
… | |
309 | |
273 | |
310 | "Cede" to other coroutines. This function puts the current coroutine into the |
274 | "Cede" to other coroutines. This function puts the current coroutine into the |
311 | ready queue and calls C<schedule>, which has the effect of giving up the |
275 | ready queue and calls C<schedule>, which has the effect of giving up the |
312 | current "timeslice" to other coroutines of the same or higher priority. |
276 | current "timeslice" to other coroutines of the same or higher priority. |
313 | |
277 | |
314 | Returns true if at least one coroutine switch has happened. |
|
|
315 | |
|
|
316 | =item Coro::cede_notself |
278 | =item Coro::cede_notself |
317 | |
279 | |
318 | Works like cede, but is not exported by default and will cede to any |
280 | Works like cede, but is not exported by default and will cede to any |
319 | coroutine, regardless of priority, once. |
281 | coroutine, regardless of priority, once. |
320 | |
|
|
321 | Returns true if at least one coroutine switch has happened. |
|
|
322 | |
282 | |
323 | =item terminate [arg...] |
283 | =item terminate [arg...] |
324 | |
284 | |
325 | Terminates the current coroutine with the given status values (see L<cancel>). |
285 | Terminates the current coroutine with the given status values (see L<cancel>). |
326 | |
286 | |
… | |
… | |
342 | if $_ != $current && UNIVERSAL::isa $_, "Coro"; |
302 | if $_ != $current && UNIVERSAL::isa $_, "Coro"; |
343 | } |
303 | } |
344 | } |
304 | } |
345 | |
305 | |
346 | =back |
306 | =back |
347 | |
|
|
348 | # dynamic methods |
|
|
349 | |
307 | |
350 | =head2 COROUTINE METHODS |
308 | =head2 COROUTINE METHODS |
351 | |
309 | |
352 | These are the methods you can call on coroutine objects. |
310 | These are the methods you can call on coroutine objects. |
353 | |
311 | |
… | |
… | |
632 | |
590 | |
633 | Event/IO: L<Coro::Timer>, L<Coro::Event>, L<Coro::Handle>, L<Coro::Socket>. |
591 | Event/IO: L<Coro::Timer>, L<Coro::Event>, L<Coro::Handle>, L<Coro::Socket>. |
634 | |
592 | |
635 | Compatibility: L<Coro::LWP>, L<Coro::Storable>, L<Coro::Select>. |
593 | Compatibility: L<Coro::LWP>, L<Coro::Storable>, L<Coro::Select>. |
636 | |
594 | |
637 | Embedding: L<Coro:MakeMaker>. |
595 | Embedding: L<Coro::MakeMaker>. |
638 | |
596 | |
639 | =head1 AUTHOR |
597 | =head1 AUTHOR |
640 | |
598 | |
641 | Marc Lehmann <schmorp@schmorp.de> |
599 | Marc Lehmann <schmorp@schmorp.de> |
642 | http://home.schmorp.de/ |
600 | http://home.schmorp.de/ |