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

Comparing Coro/Coro.pm (file contents):
Revision 1.132 by root, Thu Sep 20 22:53:23 2007 UTC vs.
Revision 1.138 by root, Wed Sep 26 19:27:04 2007 UTC

50 50
51our $idle; # idle handler 51our $idle; # idle handler
52our $main; # main coroutine 52our $main; # main coroutine
53our $current; # current coroutine 53our $current; # current coroutine
54 54
55our $VERSION = '3.7'; 55our $VERSION = '3.8';
56 56
57our @EXPORT = qw(async async_pool cede schedule terminate current unblock_sub); 57our @EXPORT = qw(async async_pool cede schedule terminate current unblock_sub);
58our %EXPORT_TAGS = ( 58our %EXPORT_TAGS = (
59 prio => [qw(PRIO_MAX PRIO_HIGH PRIO_NORMAL PRIO_LOW PRIO_IDLE PRIO_MIN)], 59 prio => [qw(PRIO_MAX PRIO_HIGH PRIO_NORMAL PRIO_LOW PRIO_IDLE PRIO_MIN)],
60); 60);
155 # call all destruction callbacks 155 # call all destruction callbacks
156 $_->(@{$self->{status}}) 156 $_->(@{$self->{status}})
157 for @{(delete $self->{destroy_cb}) || []}; 157 for @{(delete $self->{destroy_cb}) || []};
158} 158}
159 159
160sub _do_trace {
161 $current->{_trace_cb}->();
162}
163
160# this coroutine is necessary because a coroutine 164# this coroutine is necessary because a coroutine
161# cannot destroy itself. 165# cannot destroy itself.
162my @destroy; 166my @destroy;
163my $manager; 167my $manager;
164 168
224The pool size is limited to 8 idle coroutines (this can be adjusted by 228The pool size is limited to 8 idle coroutines (this can be adjusted by
225changing $Coro::POOL_SIZE), and there can be as many non-idle coros as 229changing $Coro::POOL_SIZE), and there can be as many non-idle coros as
226required. 230required.
227 231
228If you are concerned about pooled coroutines growing a lot because a 232If you are concerned about pooled coroutines growing a lot because a
229single C<async_pool> used a lot of stackspace you can e.g. C<async_pool { 233single C<async_pool> used a lot of stackspace you can e.g. C<async_pool
230terminate }> once per second or so to slowly replenish the pool. 234{ terminate }> once per second or so to slowly replenish the pool. In
235addition to that, when the stacks used by a handler grows larger than 16kb
236(adjustable with $Coro::POOL_RSS) it will also exit.
231 237
232=cut 238=cut
233 239
234our $POOL_SIZE = 8; 240our $POOL_SIZE = 8;
235our $MAX_POOL_RSS = 64 * 1024; 241our $POOL_RSS = 16 * 1024;
236our @pool; 242our @async_pool;
237 243
238sub pool_handler { 244sub pool_handler {
245 my $cb;
246
239 while () { 247 while () {
240 $current->{desc} = "[async_pool]";
241
242 eval { 248 eval {
243 my ($cb, @arg) = @{ delete $current->{_invoke} or return }; 249 while () {
244 $cb->(@arg); 250 _pool_1 $cb;
251 &$cb;
252 _pool_2 $cb;
253 &schedule;
254 }
245 }; 255 };
256
257 last if $@ eq "\3terminate\2\n";
246 warn $@ if $@; 258 warn $@ if $@;
247
248 last if @pool >= $POOL_SIZE || $current->rss >= $MAX_POOL_RSS;
249
250 push @pool, $current;
251 $current->{desc} = "[async_pool idle]";
252 $current->save (Coro::State::SAVE_DEF);
253 $current->prio (0);
254 schedule;
255 } 259 }
256} 260}
257 261
258sub async_pool(&@) { 262sub async_pool(&@) {
259 # this is also inlined into the unlock_scheduler 263 # this is also inlined into the unlock_scheduler
260 my $coro = (pop @pool) || new Coro \&pool_handler;; 264 my $coro = (pop @async_pool) || new Coro \&pool_handler;
261 265
262 $coro->{_invoke} = [@_]; 266 $coro->{_invoke} = [@_];
263 $coro->ready; 267 $coro->ready;
264 268
265 $coro 269 $coro
535# inside an event callback. 539# inside an event callback.
536our $unblock_scheduler = new Coro sub { 540our $unblock_scheduler = new Coro sub {
537 while () { 541 while () {
538 while (my $cb = pop @unblock_queue) { 542 while (my $cb = pop @unblock_queue) {
539 # this is an inlined copy of async_pool 543 # this is an inlined copy of async_pool
540 my $coro = (pop @pool or new Coro \&pool_handler); 544 my $coro = (pop @async_pool) || new Coro \&pool_handler;
541 545
542 $coro->{_invoke} = $cb; 546 $coro->{_invoke} = $cb;
543 $coro->ready; 547 $coro->ready;
544 cede; # for short-lived callbacks, this reduces pressure on the coro pool 548 cede; # for short-lived callbacks, this reduces pressure on the coro pool
545 } 549 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines