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

Comparing AnyEvent/lib/AnyEvent.pm (file contents):
Revision 1.19 by root, Sun Dec 10 23:59:15 2006 UTC vs.
Revision 1.20 by root, Mon Dec 11 01:16:09 2006 UTC

160=back 160=back
161 161
162=head2 SIGNAL WATCHERS 162=head2 SIGNAL WATCHERS
163 163
164You can listen for signals using a signal watcher, C<signal> is the signal 164You can listen for signals using a signal watcher, C<signal> is the signal
165I<name> without any C<SIG> prefix. 165I<name> without any C<SIG> prefix. Multiple signals events can be clumped
166together into one callback invocation, and callbakc invocation might or
167might not be asynchronous.
166 168
167These watchers might use C<%SIG>, so programs overwriting those signals 169These watchers might use C<%SIG>, so programs overwriting those signals
168directly will likely not work correctly. 170directly will likely not work correctly.
169 171
170Example: exit on SIGINT 172Example: exit on SIGINT
171 173
172 my $w = AnyEvent->signal (signal => "INT", cb => sub { exit 1 }); 174 my $w = AnyEvent->signal (signal => "INT", cb => sub { exit 1 });
175
176=head2 CHILD PROCESS WATCHERS
177
178You can also listen for the status of a child process specified by the
179C<pid> argument. The watcher will only trigger once. This works by
180installing a signal handler for C<SIGCHLD>.
181
182Example: wait for pid 1333
183
184 my $w = AnyEvent->child (pid => 1333, cb => sub { warn "exit status $?" });
173 185
174=head1 GLOBALS 186=head1 GLOBALS
175 187
176=over 4 188=over 4
177 189
308 $class->$func (@_); 320 $class->$func (@_);
309} 321}
310 322
311package AnyEvent::Base; 323package AnyEvent::Base;
312 324
325# default implementation for ->condvar, ->wait, ->broadcast
326
327sub condvar {
328 bless \my $flag, "AnyEvent::Base::CondVar"
329}
330
331sub AnyEvent::Base::CondVar::broadcast {
332 ${$_[0]}++;
333}
334
335sub AnyEvent::Base::CondVar::wait {
336 AnyEvent->one_event while !${$_[0]};
337}
338
313# default implementation for signal 339# default implementation for ->signal
314 340
315our %SIG_CB; 341our %SIG_CB;
316 342
317sub signal { 343sub signal {
318 my (undef, %arg) = @_; 344 my (undef, %arg) = @_;
319 345
320 my $signal = uc $arg{signal} 346 my $signal = uc $arg{signal}
321 or Carp::croak "required option 'signal' is missing"; 347 or Carp::croak "required option 'signal' is missing";
322 348
323 my $w = bless [$signal, $arg{cb}], "AnyEvent::Base::Signal";
324
325 $SIG_CB{$signal}{$arg{cb}} = $arg{cb}; 349 $SIG_CB{$signal}{$arg{cb}} = $arg{cb};
326 $SIG{$signal} ||= sub { 350 $SIG{$signal} ||= sub {
327 $_->() for values %{ $SIG_CB{$signal} }; 351 $_->() for values %{ $SIG_CB{$signal} || {} };
328 }; 352 };
329 353
330 $w 354 bless [$signal, $arg{cb}], "AnyEvent::Base::Signal"
331} 355}
332 356
333sub AnyEvent::Base::Signal::DESTROY { 357sub AnyEvent::Base::Signal::DESTROY {
334 my ($signal, $cb) = @{$_[0]}; 358 my ($signal, $cb) = @{$_[0]};
335 359
336 delete $SIG_CB{$signal}{$cb}; 360 delete $SIG_CB{$signal}{$cb};
337 361
338 $SIG{$signal} = 'DEFAULT' unless keys %{ $SIG_CB{$signal} }; 362 $SIG{$signal} = 'DEFAULT' unless keys %{ $SIG_CB{$signal} };
363}
364
365# default implementation for ->child
366
367our %PID_CB;
368our $CHLD_W;
369our $PID_IDLE;
370our $WNOHANG;
371
372sub _child_wait {
373 while (0 < (my $pid = waitpid -1, $WNOHANG)) {
374 $_->() for values %{ (delete $PID_CB{$pid}) || {} };
375 }
376
377 undef $PID_IDLE;
378}
379
380sub child {
381 my (undef, %arg) = @_;
382
383 my $pid = uc $arg{pid}
384 or Carp::croak "required option 'pid' is missing";
385
386 $PID_CB{$pid}{$arg{cb}} = $arg{cb};
387
388 unless ($WNOHANG) {
389 $CHLD_W = AnyEvent->signal (signal => 'CHLD', cb => \&_child_wait);
390 $WNOHANG = eval { require POSIX; &POSIX::WNOHANG } || 1;
391 }
392
393 # child could be a zombie already
394 $PID_IDLE ||= AnyEvent->timer (after => 0, cb => \&_child_wait);
395
396 bless [$pid, $arg{cb}], "AnyEvent::Base::Child"
397}
398
399sub AnyEvent::Base::Child::DESTROY {
400 my ($pid, $cb) = @{$_[0]};
401
402 delete $PID_CB{$pid}{$cb};
403 delete $PID_CB{$pid} unless keys %{ $PID_CB{$pid} };
404
405 undef $CHLD_W unless keys %PID_CB;
339} 406}
340 407
341=head1 SUPPLYING YOUR OWN EVENT MODEL INTERFACE 408=head1 SUPPLYING YOUR OWN EVENT MODEL INTERFACE
342 409
343If you need to support another event library which isn't directly 410If you need to support another event library which isn't directly

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines