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.263 by root, Wed Jul 29 12:39:21 2009 UTC vs.
Revision 1.265 by root, Wed Jul 29 13:10:58 2009 UTC

1334sub _sig_del { 1334sub _sig_del {
1335 undef $SIG_TW 1335 undef $SIG_TW
1336 unless --$SIG_COUNT; 1336 unless --$SIG_COUNT;
1337} 1337}
1338 1338
1339our %SIGNAME2NUM;
1340our @SIGNUM2NAME;
1341our $_sig_name_init; $_sig_name_init = sub { 1339our $_sig_name_init; $_sig_name_init = sub {
1340 eval q{ # poor man's autoloading
1342 undef $_sig_name_init; 1341 undef $_sig_name_init;
1343 1342
1344 if (_have_async_interrupt) { 1343 if (_have_async_interrupt) {
1345 *sig2num = \&Async::Interrupt::sig2num; 1344 *sig2num = \&Async::Interrupt::sig2num;
1346 *sig2name = \&Async::Interrupt::sig2name; 1345 *sig2name = \&Async::Interrupt::sig2name;
1347 } else { 1346 } else {
1348 require Config; 1347 require Config;
1349 1348
1349 my %signame2num;
1350 @SIGNAME2NUM{ split ' ', $Config::Config{sig_name} } 1350 @signame2num{ split ' ', $Config::Config{sig_name} }
1351 = split ' ', $Config::Config{sig_num}; 1351 = split ' ', $Config::Config{sig_num};
1352 @SIGNUM2NAME[values %SIGNAME2NUM] = keys %SIGNAME2NUM;
1353 1352
1353 my @signum2name;
1354 @signum2name[values %signame2num] = keys %signame2num;
1355
1354 *sig2num = sub($) { 1356 *sig2num = sub($) {
1355 $_[0] > 0 ? shift : $SIGNAME2NUM{+shift} 1357 $_[0] > 0 ? shift : $signame2num{+shift}
1356 }; 1358 };
1357 *sig2name = sub ($) { 1359 *sig2name = sub ($) {
1358 $_[0] > 0 ? $SIGNUM2NAME[+shift] : shift 1360 $_[0] > 0 ? $signum2name[+shift] : shift
1361 };
1359 }; 1362 }
1360 } 1363 };
1364 die if $@;
1361}; 1365};
1362 1366
1363sub sig2num ($) { &$_sig_name_init; &sig2num } 1367sub sig2num ($) { &$_sig_name_init; &sig2num }
1364sub sig2name($) { &$_sig_name_init; &sig2name } 1368sub sig2name($) { &$_sig_name_init; &sig2name }
1365 1369
1366sub _signal { 1370sub signal {
1371 eval q{ # poor man's autoloading {}
1372 # probe for availability of Async::Interrupt
1373 if (_have_async_interrupt) {
1374 warn "AnyEvent: using Async::Interrupt for race-free signal handling.\n" if $VERBOSE >= 8;
1375
1376 $SIGPIPE_R = new Async::Interrupt::EventPipe;
1377 $SIG_IO = AnyEvent->io (fh => $SIGPIPE_R->fileno, poll => "r", cb => \&_signal_exec);
1378
1379 } else {
1380 warn "AnyEvent: using emulated perl signal handling with latency timer.\n" if $VERBOSE >= 8;
1381
1382 require Fcntl;
1383
1384 if (AnyEvent::WIN32) {
1385 require AnyEvent::Util;
1386
1387 ($SIGPIPE_R, $SIGPIPE_W) = AnyEvent::Util::portable_pipe ();
1388 AnyEvent::Util::fh_nonblocking ($SIGPIPE_R, 1) if $SIGPIPE_R;
1389 AnyEvent::Util::fh_nonblocking ($SIGPIPE_W, 1) if $SIGPIPE_W; # just in case
1390 } else {
1391 pipe $SIGPIPE_R, $SIGPIPE_W;
1392 fcntl $SIGPIPE_R, &Fcntl::F_SETFL, &Fcntl::O_NONBLOCK if $SIGPIPE_R;
1393 fcntl $SIGPIPE_W, &Fcntl::F_SETFL, &Fcntl::O_NONBLOCK if $SIGPIPE_W; # just in case
1394
1395 # not strictly required, as $^F is normally 2, but let's make sure...
1396 fcntl $SIGPIPE_R, &Fcntl::F_SETFD, &Fcntl::FD_CLOEXEC;
1397 fcntl $SIGPIPE_W, &Fcntl::F_SETFD, &Fcntl::FD_CLOEXEC;
1398 }
1399
1400 $SIGPIPE_R
1401 or Carp::croak "AnyEvent: unable to create a signal reporting pipe: $!\n";
1402
1403 $SIG_IO = AnyEvent->io (fh => $SIGPIPE_R, poll => "r", cb => \&_signal_exec);
1404 }
1405
1406 *signal = sub {
1367 my (undef, %arg) = @_; 1407 my (undef, %arg) = @_;
1368 1408
1369 my $signal = uc $arg{signal} 1409 my $signal = uc $arg{signal}
1370 or Carp::croak "required option 'signal' is missing"; 1410 or Carp::croak "required option 'signal' is missing";
1371 1411
1372 if ($HAVE_ASYNC_INTERRUPT) { 1412 if ($HAVE_ASYNC_INTERRUPT) {
1373 # async::interrupt 1413 # async::interrupt
1374 1414
1375 $signal = sig2num $signal; 1415 $signal = sig2num $signal;
1376 $SIG_CB{$signal}{$arg{cb}} = $arg{cb}; 1416 $SIG_CB{$signal}{$arg{cb}} = $arg{cb};
1377 1417
1378 $SIG_ASY{$signal} ||= new Async::Interrupt 1418 $SIG_ASY{$signal} ||= new Async::Interrupt
1379 cb => sub { undef $SIG_EV{$signal} }, 1419 cb => sub { undef $SIG_EV{$signal} },
1380 signal => $signal, 1420 signal => $signal,
1381 pipe => [$SIGPIPE_R->filenos], 1421 pipe => [$SIGPIPE_R->filenos],
1382 pipe_autodrain => 0, 1422 pipe_autodrain => 0,
1383 ; 1423 ;
1384 1424
1385 } else { 1425 } else {
1386 # pure perl 1426 # pure perl
1387 1427
1388 # AE::Util has been loaded in signal 1428 # AE::Util has been loaded in signal
1389 $signal = sig2name $signal; 1429 $signal = sig2name $signal;
1390 $SIG_CB{$signal}{$arg{cb}} = $arg{cb}; 1430 $SIG_CB{$signal}{$arg{cb}} = $arg{cb};
1391 1431
1392 $SIG{$signal} ||= sub { 1432 $SIG{$signal} ||= sub {
1393 local $!; 1433 local $!;
1394 syswrite $SIGPIPE_W, "\x00", 1 unless %SIG_EV; 1434 syswrite $SIGPIPE_W, "\x00", 1 unless %SIG_EV;
1395 undef $SIG_EV{$signal}; 1435 undef $SIG_EV{$signal};
1436 };
1437
1438 # can't do signal processing without introducing races in pure perl,
1439 # so limit the signal latency.
1440 _sig_add;
1441 }
1442
1443 bless [$signal, $arg{cb}], "AnyEvent::Base::signal"
1396 }; 1444 };
1397 1445
1398 # can't do signal processing without introducing races in pure perl, 1446 *AnyEvent::Base::signal::DESTROY = sub {
1399 # so limit the signal latency. 1447 my ($signal, $cb) = @{$_[0]};
1448
1400 _sig_add; 1449 _sig_del;
1401 }
1402 1450
1403 bless [$signal, $arg{cb}], "AnyEvent::Base::signal" 1451 delete $SIG_CB{$signal}{$cb};
1404}
1405 1452
1406sub signal { 1453 $HAVE_ASYNC_INTERRUPT
1407 # probe for availability of Async::Interrupt 1454 ? delete $SIG_ASY{$signal}
1408 if (_have_async_interrupt) { 1455 : # delete doesn't work with older perls - they then
1409 warn "AnyEvent: using Async::Interrupt for race-free signal handling.\n" if $VERBOSE >= 8; 1456 # print weird messages, or just unconditionally exit
1410 1457 # instead of getting the default action.
1411 $SIGPIPE_R = new Async::Interrupt::EventPipe; 1458 undef $SIG{$signal}
1412 $SIG_IO = AnyEvent->io (fh => $SIGPIPE_R->fileno, poll => "r", cb => \&_signal_exec); 1459 unless keys %{ $SIG_CB{$signal} };
1413
1414 } else {
1415 warn "AnyEvent: using emulated perl signal handling with latency timer.\n" if $VERBOSE >= 8;
1416
1417 require Fcntl;
1418
1419 if (AnyEvent::WIN32) {
1420 require AnyEvent::Util;
1421
1422 ($SIGPIPE_R, $SIGPIPE_W) = AnyEvent::Util::portable_pipe ();
1423 AnyEvent::Util::fh_nonblocking ($SIGPIPE_R) if $SIGPIPE_R;
1424 AnyEvent::Util::fh_nonblocking ($SIGPIPE_W) if $SIGPIPE_W; # just in case
1425 } else {
1426 pipe $SIGPIPE_R, $SIGPIPE_W;
1427 fcntl $SIGPIPE_R, &Fcntl::F_SETFL, &Fcntl::O_NONBLOCK if $SIGPIPE_R;
1428 fcntl $SIGPIPE_W, &Fcntl::F_SETFL, &Fcntl::O_NONBLOCK if $SIGPIPE_W; # just in case
1429
1430 # not strictly required, as $^F is normally 2, but let's make sure...
1431 fcntl $SIGPIPE_R, &Fcntl::F_SETFD, &Fcntl::FD_CLOEXEC;
1432 fcntl $SIGPIPE_W, &Fcntl::F_SETFD, &Fcntl::FD_CLOEXEC;
1433 } 1460 };
1434
1435 $SIGPIPE_R
1436 or Carp::croak "AnyEvent: unable to create a signal reporting pipe: $!\n";
1437
1438 $SIG_IO = AnyEvent->io (fh => $SIGPIPE_R, poll => "r", cb => \&_signal_exec);
1439 } 1461 };
1440 1462 die if $@;
1441 *signal = \&_signal;
1442 &signal 1463 &signal
1443}
1444
1445sub AnyEvent::Base::signal::DESTROY {
1446 my ($signal, $cb) = @{$_[0]};
1447
1448 _sig_del;
1449
1450 delete $SIG_CB{$signal}{$cb};
1451
1452 $HAVE_ASYNC_INTERRUPT
1453 ? delete $SIG_ASY{$signal}
1454 : # delete doesn't work with older perls - they then
1455 # print weird messages, or just unconditionally exit
1456 # instead of getting the default action.
1457 undef $SIG{$signal}
1458 unless keys %{ $SIG_CB{$signal} };
1459} 1464}
1460 1465
1461# default implementation for ->child 1466# default implementation for ->child
1462 1467
1463our %PID_CB; 1468our %PID_CB;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines