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

Comparing Coro/Coro.pm (file contents):
Revision 1.229 by root, Thu Nov 20 06:32:55 2008 UTC vs.
Revision 1.233 by root, Fri Nov 21 06:02:07 2008 UTC

67 67
68our $idle; # idle handler 68our $idle; # idle handler
69our $main; # main coroutine 69our $main; # main coroutine
70our $current; # current coroutine 70our $current; # current coroutine
71 71
72our $VERSION = 5.0; 72our $VERSION = "5.0";
73 73
74our @EXPORT = qw(async async_pool cede schedule terminate current unblock_sub); 74our @EXPORT = qw(async async_pool cede schedule terminate current unblock_sub);
75our %EXPORT_TAGS = ( 75our %EXPORT_TAGS = (
76 prio => [qw(PRIO_MAX PRIO_HIGH PRIO_NORMAL PRIO_LOW PRIO_IDLE PRIO_MIN)], 76 prio => [qw(PRIO_MAX PRIO_HIGH PRIO_NORMAL PRIO_LOW PRIO_IDLE PRIO_MIN)],
77); 77);
135$idle = sub { 135$idle = sub {
136 require Carp; 136 require Carp;
137 Carp::croak ("FATAL: deadlock detected"); 137 Carp::croak ("FATAL: deadlock detected");
138}; 138};
139 139
140sub _cancel {
141 my ($self) = @_;
142
143 # free coroutine data and mark as destructed
144 $self->_destroy
145 or return;
146
147 # call all destruction callbacks
148 $_->(@{$self->{_status}})
149 for @{ delete $self->{_on_destroy} || [] };
150}
151
152# this coroutine is necessary because a coroutine 140# this coroutine is necessary because a coroutine
153# cannot destroy itself. 141# cannot destroy itself.
154our @destroy; 142our @destroy;
155our $manager; 143our $manager;
156 144
157$manager = new Coro sub { 145$manager = new Coro sub {
158 while () { 146 while () {
159 (shift @destroy)->_cancel 147 Coro::_cancel shift @destroy
160 while @destroy; 148 while @destroy;
161 149
162 &schedule; 150 &schedule;
163 } 151 }
164}; 152};
237coros as required. 225coros as required.
238 226
239If you are concerned about pooled coroutines growing a lot because a 227If you are concerned about pooled coroutines growing a lot because a
240single C<async_pool> used a lot of stackspace you can e.g. C<async_pool 228single C<async_pool> used a lot of stackspace you can e.g. C<async_pool
241{ terminate }> once per second or so to slowly replenish the pool. In 229{ terminate }> once per second or so to slowly replenish the pool. In
242addition to that, when the stacks used by a handler grows larger than 16kb 230addition to that, when the stacks used by a handler grows larger than 32kb
243(adjustable via $Coro::POOL_RSS) it will also be destroyed. 231(adjustable via $Coro::POOL_RSS) it will also be destroyed.
244 232
245=cut 233=cut
246 234
247our $POOL_SIZE = 8; 235our $POOL_SIZE = 8;
248our $POOL_RSS = 16 * 1024; 236our $POOL_RSS = 32 * 1024;
249our @async_pool; 237our @async_pool;
250 238
251sub pool_handler { 239sub pool_handler {
252 while () { 240 while () {
253 eval { 241 eval {
319you cannot free all of them, so if a coroutine that is not the main 307you cannot free all of them, so if a coroutine that is not the main
320program calls this function, there will be some one-time resource leak. 308program calls this function, there will be some one-time resource leak.
321 309
322=cut 310=cut
323 311
324sub terminate {
325 $current->{_status} = [@_];
326 push @destroy, $current;
327 $manager->ready;
328 do { &schedule } while 1;
329}
330
331sub killall { 312sub killall {
332 for (Coro::State::list) { 313 for (Coro::State::list) {
333 $_->cancel 314 $_->cancel
334 if $_ != $current && UNIVERSAL::isa $_, "Coro"; 315 if $_ != $current && UNIVERSAL::isa $_, "Coro";
335 } 316 }
515 496
516sub desc { 497sub desc {
517 my $old = $_[0]{desc}; 498 my $old = $_[0]{desc};
518 $_[0]{desc} = $_[1] if @_ > 1; 499 $_[0]{desc} = $_[1] if @_ > 1;
519 $old; 500 $old;
501}
502
503sub transfer {
504 require Carp;
505 Carp::croak ("You must not call ->transfer on Coro objects. Use Coro::State objects or the ->schedule_to method. Caught");
520} 506}
521 507
522=back 508=back
523 509
524=head2 GLOBAL FUNCTIONS 510=head2 GLOBAL FUNCTIONS

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines