ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/lib/AnyEvent/Impl/POE.pm
(Generate patch)

Comparing AnyEvent/lib/AnyEvent/Impl/POE.pm (file contents):
Revision 1.22 by root, Fri Oct 3 07:19:23 2008 UTC vs.
Revision 1.25 by root, Sun Jun 28 11:43:51 2009 UTC

113 113
114=item Event Non-Ordering 114=item Event Non-Ordering
115 115
116POE cannot guarentee the order of callback invocation for timers, and 116POE cannot guarentee the order of callback invocation for timers, and
117usually gets it wrong. That is, if you have two timers, one timing out 117usually gets it wrong. That is, if you have two timers, one timing out
118after another (all els ebeing equal), the callbacks might be called in 118after another (all else being equal), the callbacks might be called in
119reverse order. 119reverse order.
120 120
121How one manages to even implement stuff that way escapes me. 121How one manages to even implement stuff that way escapes me.
122 122
123=item Child Watchers 123=item Child Watchers
124 124
125POE offers child watchers - which is a laudable thing, as few event loops 125POE offers child watchers - which is a laudable thing, as few event loops
126do. Unfortunately, they cannot even implement AnyEvent's simple child 126do. Unfortunately, they cannot even implement AnyEvent's simple child
127watchers: they are not generic enough (even the POE implementation itself 127watchers: they are not generic enough (the POE implementation isn't even
128isn't generic enough to let properly designed event loops such as EV use 128generic enough to let properly designed back-end use their native child
129their child watcher instead - it insist on doing it itself the slow way). 129watcher instead - it insist on doing it itself the broken way).
130 130
131Unfortunately, POE's child handling is inherently racy: if the child
132exits before the handler is created (which is impossible to avoid in
133general, imagine the forked program to exit immediately because of a
134bug, or imagine the POE kernel being busy for a second), one has to
135wait for another event to occur, which can take an indefinite amount of
136time. Apparently POE implements a busy-waiting loop every second, but this
137is not guaranteed or documented, so in practise child status events can be
138delayed for up to a second "only".
139
131Of course, if POE reaps an unrelated child it will also output a message 140Of course, whenever POE reaps an unrelated child it will also output a
132for it that you cannot suppress (which shouldn't be too surprising at this 141message for it that you cannot suppress (which shouldn't be too surprising
133point). Very professional. 142at this point). Very professional.
134 143
135As a workaround, AnyEvent::Impl::POE will take advantage of undocumented 144As a workaround, AnyEvent::Impl::POE will take advantage of undocumented
136behaviour in POE::Kernel to catch the status of all child processes. 145behaviour in POE::Kernel to catch the status of all child processes, but
137 146it cannot guarantee delivery.
138Unfortunately, POE's child handling is racy: if the child exits before the
139handler is created (which is impossible to avoid in general), one has to
140wait for another event to occur, which can take an indefinite amount of
141time (apparently POE does a busy-waiting loop every second, but this is
142not guarenteed or documented, so in practise child status events can be
143delayed for up to a second "only" at least in the current version).
144 147
145How one manages to have such a glaring bug in an event loop after ten 148How one manages to have such a glaring bug in an event loop after ten
146years of development escapes me. 149years of development escapes me.
147 150
148=item Documentation Quality 151=item Documentation Quality
241course, as both are O(n) in the number of file descriptors, which is 244course, as both are O(n) in the number of file descriptors, which is
242rather bad. 245rather bad.
243 246
244This is just one place where it gets obvious how little the author of the 247This is just one place where it gets obvious how little the author of the
245POE manpage understands. 248POE manpage understands.
249
250=item No idle events
251
252The POE-recommended workaround to this is apparently to use
253C<fork>. Consequently, idle watchera will have to be emulated by AnyEvent.
246 254
247=back 255=back
248 256
249On the good side, AnyEvent allows you to write your modules in a 100% 257On the good side, AnyEvent allows you to write your modules in a 100%
250POE-compatible way (bug-for-bug compatible even), without forcing your 258POE-compatible way (bug-for-bug compatible even), without forcing your
295 stop => sub { 303 stop => sub {
296 $_[KERNEL]->$pee ($fh); 304 $_[KERNEL]->$pee ($fh);
297 }, 305 },
298 }, 306 },
299 ); 307 );
300 bless \\$session, AnyEvent::Impl::POE:: 308 bless \\$session, "AnyEvent::Impl::POE"
301} 309}
302 310
303sub timer { 311sub timer {
304 my ($class, %arg) = @_; 312 my ($class, %arg) = @_;
305 313
316 stop => sub { 324 stop => sub {
317 $_[KERNEL]->alarm_remove_all; 325 $_[KERNEL]->alarm_remove_all;
318 }, 326 },
319 }, 327 },
320 ); 328 );
321 bless \\$session, AnyEvent::Impl::POE:: 329 bless \\$session, "AnyEvent::Impl::POE"
322} 330}
323 331
324sub signal { 332sub signal {
325 my ($class, %arg) = @_; 333 my ($class, %arg) = @_;
326 my $signal = delete $arg{signal}; 334 my $signal = delete $arg{signal};
339 $_[KERNEL]->refcount_decrement ($_[SESSION]->ID => "poe"); 347 $_[KERNEL]->refcount_decrement ($_[SESSION]->ID => "poe");
340 $_[KERNEL]->sig ($signal); 348 $_[KERNEL]->sig ($signal);
341 }, 349 },
342 }, 350 },
343 ); 351 );
344 bless \\$session, AnyEvent::Impl::POE:: 352 bless \\$session, "AnyEvent::Impl::POE"
345} 353}
346 354
347sub child { 355sub child {
348 my ($class, %arg) = @_; 356 my ($class, %arg) = @_;
349 my $pid = delete $arg{pid}; 357 my $pid = delete $arg{pid};
363 $_[KERNEL]->refcount_decrement ($_[SESSION]->ID => "poe"); 371 $_[KERNEL]->refcount_decrement ($_[SESSION]->ID => "poe");
364 $_[KERNEL]->sig ("CHLD"); 372 $_[KERNEL]->sig ("CHLD");
365 }, 373 },
366 }, 374 },
367 ); 375 );
368 bless \\$session, AnyEvent::Impl::POE:: 376 bless \\$session, "AnyEvent::Impl::POE"
369} 377}
370 378
371sub DESTROY { 379sub DESTROY {
372 POE::Kernel->post (${${$_[0]}}, "stop"); 380 POE::Kernel->post (${${$_[0]}}, "stop");
373} 381}
374 382
375sub one_event { 383sub one_event {
376 POE::Kernel->loop_do_timeslice; 384 POE::Kernel->loop_do_timeslice;
377} 385}
378 386
387sub loop {
388 POE::Kernel->run;
389}
390
3791; 3911;
380 392
381=head1 SEE ALSO 393=head1 SEE ALSO
382 394
383L<AnyEvent>, L<POE>. 395L<AnyEvent>, L<POE>.

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines