… | |
… | |
67 | |
67 | |
68 | our $idle; # idle handler |
68 | our $idle; # idle handler |
69 | our $main; # main coroutine |
69 | our $main; # main coroutine |
70 | our $current; # current coroutine |
70 | our $current; # current coroutine |
71 | |
71 | |
72 | our $VERSION = 5.0; |
72 | our $VERSION = "5.0"; |
73 | |
73 | |
74 | our @EXPORT = qw(async async_pool cede schedule terminate current unblock_sub); |
74 | our @EXPORT = qw(async async_pool cede schedule terminate current unblock_sub); |
75 | our %EXPORT_TAGS = ( |
75 | our %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 | |
140 | sub _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. |
154 | our @destroy; |
142 | our @destroy; |
155 | our $manager; |
143 | our $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 | }; |
… | |
… | |
212 | Similar to C<async>, but uses a coroutine pool, so you should not call |
200 | Similar to C<async>, but uses a coroutine pool, so you should not call |
213 | terminate or join on it (although you are allowed to), and you get a |
201 | terminate or join on it (although you are allowed to), and you get a |
214 | coroutine that might have executed other code already (which can be good |
202 | coroutine that might have executed other code already (which can be good |
215 | or bad :). |
203 | or bad :). |
216 | |
204 | |
217 | On the plus side, this function is faster than creating (and destroying) |
205 | On the plus side, this function is about twice as fast as creating (and |
218 | a completly new coroutine, so if you need a lot of generic coroutines in |
206 | destroying) a completely new coroutine, so if you need a lot of generic |
219 | quick successsion, use C<async_pool>, not C<async>. |
207 | coroutines in quick successsion, use C<async_pool>, not C<async>. |
220 | |
208 | |
221 | The code block is executed in an C<eval> context and a warning will be |
209 | The code block is executed in an C<eval> context and a warning will be |
222 | issued in case of an exception instead of terminating the program, as |
210 | issued in case of an exception instead of terminating the program, as |
223 | C<async> does. As the coroutine is being reused, stuff like C<on_destroy> |
211 | C<async> does. As the coroutine is being reused, stuff like C<on_destroy> |
224 | will not work in the expected way, unless you call terminate or cancel, |
212 | will not work in the expected way, unless you call terminate or cancel, |
… | |
… | |
237 | coros as required. |
225 | coros as required. |
238 | |
226 | |
239 | If you are concerned about pooled coroutines growing a lot because a |
227 | If you are concerned about pooled coroutines growing a lot because a |
240 | single C<async_pool> used a lot of stackspace you can e.g. C<async_pool |
228 | single 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 |
242 | addition to that, when the stacks used by a handler grows larger than 16kb |
230 | addition 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 | |
247 | our $POOL_SIZE = 8; |
235 | our $POOL_SIZE = 8; |
248 | our $POOL_RSS = 16 * 1024; |
236 | our $POOL_RSS = 32 * 1024; |
249 | our @async_pool; |
237 | our @async_pool; |
250 | |
238 | |
251 | sub pool_handler { |
239 | sub pool_handler { |
252 | while () { |
240 | while () { |
253 | eval { |
241 | eval { |
… | |
… | |
319 | you cannot free all of them, so if a coroutine that is not the main |
307 | you cannot free all of them, so if a coroutine that is not the main |
320 | program calls this function, there will be some one-time resource leak. |
308 | program calls this function, there will be some one-time resource leak. |
321 | |
309 | |
322 | =cut |
310 | =cut |
323 | |
311 | |
324 | sub terminate { |
|
|
325 | $current->{_status} = [@_]; |
|
|
326 | push @destroy, $current; |
|
|
327 | $manager->ready; |
|
|
328 | do { &schedule } while 1; |
|
|
329 | } |
|
|
330 | |
|
|
331 | sub killall { |
312 | sub 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 | } |
… | |
… | |
391 | $self->{_status} = [@_]; |
372 | $self->{_status} = [@_]; |
392 | $self->_cancel; |
373 | $self->_cancel; |
393 | } |
374 | } |
394 | } |
375 | } |
395 | |
376 | |
|
|
377 | =item $coroutine->schedule_to |
|
|
378 | |
|
|
379 | Puts the current coroutine to sleep (like C<Coro::schedule>), but instead |
|
|
380 | of continuing with the next coro from the ready queue, always switch to |
|
|
381 | the given coroutine object (regardless of priority etc.). The readyness |
|
|
382 | state of that coroutine isn't changed. |
|
|
383 | |
|
|
384 | This is an advanced method for special cases - I'd love to hear about any |
|
|
385 | uses for this one. |
|
|
386 | |
|
|
387 | =item $coroutine->cede_to |
|
|
388 | |
|
|
389 | Like C<schedule_to>, but puts the current coroutine into the ready |
|
|
390 | queue. This has the effect of temporarily switching to the given |
|
|
391 | coroutine, and continuing some time later. |
|
|
392 | |
|
|
393 | This is an advanced method for special cases - I'd love to hear about any |
|
|
394 | uses for this one. |
|
|
395 | |
396 | =item $coroutine->throw ([$scalar]) |
396 | =item $coroutine->throw ([$scalar]) |
397 | |
397 | |
398 | If C<$throw> is specified and defined, it will be thrown as an exception |
398 | If C<$throw> is specified and defined, it will be thrown as an exception |
399 | inside the coroutine at the next convenient point in time. Otherwise |
399 | inside the coroutine at the next convenient point in time. Otherwise |
400 | clears the exception object. |
400 | clears the exception object. |
… | |
… | |
496 | |
496 | |
497 | sub desc { |
497 | sub desc { |
498 | my $old = $_[0]{desc}; |
498 | my $old = $_[0]{desc}; |
499 | $_[0]{desc} = $_[1] if @_ > 1; |
499 | $_[0]{desc} = $_[1] if @_ > 1; |
500 | $old; |
500 | $old; |
|
|
501 | } |
|
|
502 | |
|
|
503 | sub 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"); |
501 | } |
506 | } |
502 | |
507 | |
503 | =back |
508 | =back |
504 | |
509 | |
505 | =head2 GLOBAL FUNCTIONS |
510 | =head2 GLOBAL FUNCTIONS |