… | |
… | |
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 | |
|
|
160 | sub _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. |
162 | my @destroy; |
166 | my @destroy; |
163 | my $manager; |
167 | my $manager; |
164 | |
168 | |
… | |
… | |
241 | my $cb; |
245 | my $cb; |
242 | |
246 | |
243 | while () { |
247 | while () { |
244 | eval { |
248 | eval { |
245 | while () { |
249 | while () { |
246 | # &{&_pool_1 or &terminate}; # crashes, would be ~5% faster |
|
|
247 | $cb = &_pool_1 |
250 | _pool_1 $cb; |
248 | or &terminate; |
|
|
249 | &$cb; |
251 | &$cb; |
250 | undef $cb; |
252 | _pool_2 $cb; |
251 | &terminate if &_pool_2; |
|
|
252 | &schedule; |
253 | &schedule; |
253 | } |
254 | } |
254 | }; |
255 | }; |
255 | |
256 | |
|
|
257 | last if $@ eq "\3terminate\2\n"; |
256 | warn $@ if $@; |
258 | warn $@ if $@; |
257 | } |
259 | } |
258 | } |
260 | } |
259 | |
261 | |
260 | sub async_pool(&@) { |
262 | sub async_pool(&@) { |