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.232 by root, Fri Nov 21 02:39:40 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 {
318Note that while this will try to free some of the main programs resources, 306Note that while this will try to free some of the main programs resources,
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
324sub terminate {
325 $current->{_status} = [@_];
326 push @destroy, $current;
327 $manager->ready;
328 do { &schedule } while 1;
329}
330 311
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";

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines