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.22 by root, Sun Dec 31 11:54:43 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 callback 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
235 247
236no warnings; 248no warnings;
237use strict; 249use strict;
238use Carp; 250use Carp;
239 251
240our $VERSION = '2.5'; 252our $VERSION = '2.51';
241our $MODEL; 253our $MODEL;
242 254
243our $AUTOLOAD; 255our $AUTOLOAD;
244our @ISA; 256our @ISA;
245 257
276 unless ($MODEL) { 288 unless ($MODEL) {
277 # try to load a model 289 # try to load a model
278 290
279 for (@REGISTRY, @models) { 291 for (@REGISTRY, @models) {
280 my ($package, $model) = @$_; 292 my ($package, $model) = @$_;
293 if (eval "require $package"
294 and ${"$package\::VERSION"} > 0
281 if (eval "require $model") { 295 and eval "require $model") {
282 $MODEL = $model; 296 $MODEL = $model;
283 warn "AnyEvent: autoprobed and loaded model '$model', using it.\n" if $verbose > 1; 297 warn "AnyEvent: autoprobed and loaded model '$model', using it.\n" if $verbose > 1;
284 last; 298 last;
285 } 299 }
286 } 300 }
308 $class->$func (@_); 322 $class->$func (@_);
309} 323}
310 324
311package AnyEvent::Base; 325package AnyEvent::Base;
312 326
327# default implementation for ->condvar, ->wait, ->broadcast
328
329sub condvar {
330 bless \my $flag, "AnyEvent::Base::CondVar"
331}
332
333sub AnyEvent::Base::CondVar::broadcast {
334 ${$_[0]}++;
335}
336
337sub AnyEvent::Base::CondVar::wait {
338 AnyEvent->one_event while !${$_[0]};
339}
340
313# default implementation for signal 341# default implementation for ->signal
314 342
315our %SIG_CB; 343our %SIG_CB;
316 344
317sub signal { 345sub signal {
318 my (undef, %arg) = @_; 346 my (undef, %arg) = @_;
319 347
320 my $signal = uc $arg{signal} 348 my $signal = uc $arg{signal}
321 or Carp::croak "required option 'signal' is missing"; 349 or Carp::croak "required option 'signal' is missing";
322 350
323 my $w = bless [$signal, $arg{cb}], "AnyEvent::Base::Signal";
324
325 $SIG_CB{$signal}{$arg{cb}} = $arg{cb}; 351 $SIG_CB{$signal}{$arg{cb}} = $arg{cb};
326 $SIG{$signal} ||= sub { 352 $SIG{$signal} ||= sub {
327 $_->() for values %{ $SIG_CB{$signal} }; 353 $_->() for values %{ $SIG_CB{$signal} || {} };
328 }; 354 };
329 355
330 $w 356 bless [$signal, $arg{cb}], "AnyEvent::Base::Signal"
331} 357}
332 358
333sub AnyEvent::Base::Signal::DESTROY { 359sub AnyEvent::Base::Signal::DESTROY {
334 my ($signal, $cb) = @{$_[0]}; 360 my ($signal, $cb) = @{$_[0]};
335 361
336 delete $SIG_CB{$signal}{$cb}; 362 delete $SIG_CB{$signal}{$cb};
337 363
338 $SIG{$signal} = 'DEFAULT' unless keys %{ $SIG_CB{$signal} }; 364 $SIG{$signal} = 'DEFAULT' unless keys %{ $SIG_CB{$signal} };
365}
366
367# default implementation for ->child
368
369our %PID_CB;
370our $CHLD_W;
371our $PID_IDLE;
372our $WNOHANG;
373
374sub _child_wait {
375 while (0 < (my $pid = waitpid -1, $WNOHANG)) {
376 $_->() for values %{ (delete $PID_CB{$pid}) || {} };
377 }
378
379 undef $PID_IDLE;
380}
381
382sub child {
383 my (undef, %arg) = @_;
384
385 my $pid = uc $arg{pid}
386 or Carp::croak "required option 'pid' is missing";
387
388 $PID_CB{$pid}{$arg{cb}} = $arg{cb};
389
390 unless ($WNOHANG) {
391 $CHLD_W = AnyEvent->signal (signal => 'CHLD', cb => \&_child_wait);
392 $WNOHANG = eval { require POSIX; &POSIX::WNOHANG } || 1;
393 }
394
395 # child could be a zombie already
396 $PID_IDLE ||= AnyEvent->timer (after => 0, cb => \&_child_wait);
397
398 bless [$pid, $arg{cb}], "AnyEvent::Base::Child"
399}
400
401sub AnyEvent::Base::Child::DESTROY {
402 my ($pid, $cb) = @{$_[0]};
403
404 delete $PID_CB{$pid}{$cb};
405 delete $PID_CB{$pid} unless keys %{ $PID_CB{$pid} };
406
407 undef $CHLD_W unless keys %PID_CB;
339} 408}
340 409
341=head1 SUPPLYING YOUR OWN EVENT MODEL INTERFACE 410=head1 SUPPLYING YOUR OWN EVENT MODEL INTERFACE
342 411
343If you need to support another event library which isn't directly 412If you need to support another event library which isn't directly

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines