1 | =head1 NAME |
1 | =head1 NAME |
2 | |
2 | |
3 | AnyEvent - events independent of event loop implementation |
3 | AnyEvent - the DBI of event loop programming |
4 | |
4 | |
5 | EV, Event, Glib, Tk, Perl, Event::Lib, Qt and POE are various supported |
5 | EV, Event, Glib, Tk, Perl, Event::Lib, Irssi, rxvt-unicode, IO::Async, Qt |
6 | event loops. |
6 | and POE are various supported event loops/environments. |
7 | |
7 | |
8 | =head1 SYNOPSIS |
8 | =head1 SYNOPSIS |
9 | |
9 | |
10 | use AnyEvent; |
10 | use AnyEvent; |
11 | |
11 | |
… | |
… | |
47 | |
47 | |
48 | There is a mailinglist for discussing all things AnyEvent, and an IRC |
48 | There is a mailinglist for discussing all things AnyEvent, and an IRC |
49 | channel, too. |
49 | channel, too. |
50 | |
50 | |
51 | See the AnyEvent project page at the B<Schmorpforge Ta-Sa Software |
51 | See the AnyEvent project page at the B<Schmorpforge Ta-Sa Software |
52 | Respository>, at L<http://anyevent.schmorp.de>, for more info. |
52 | Repository>, at L<http://anyevent.schmorp.de>, for more info. |
53 | |
53 | |
54 | =head1 WHY YOU SHOULD USE THIS MODULE (OR NOT) |
54 | =head1 WHY YOU SHOULD USE THIS MODULE (OR NOT) |
55 | |
55 | |
56 | Glib, POE, IO::Async, Event... CPAN offers event models by the dozen |
56 | Glib, POE, IO::Async, Event... CPAN offers event models by the dozen |
57 | nowadays. So what is different about AnyEvent? |
57 | nowadays. So what is different about AnyEvent? |
… | |
… | |
1086 | |
1086 | |
1087 | BEGIN { AnyEvent::common_sense } |
1087 | BEGIN { AnyEvent::common_sense } |
1088 | |
1088 | |
1089 | use Carp (); |
1089 | use Carp (); |
1090 | |
1090 | |
1091 | our $VERSION = 4.86; |
1091 | our $VERSION = 4.881; |
1092 | our $MODEL; |
1092 | our $MODEL; |
1093 | |
1093 | |
1094 | our $AUTOLOAD; |
1094 | our $AUTOLOAD; |
1095 | our @ISA; |
1095 | our @ISA; |
1096 | |
1096 | |
… | |
… | |
1289 | } |
1289 | } |
1290 | |
1290 | |
1291 | # default implementation for ->signal |
1291 | # default implementation for ->signal |
1292 | |
1292 | |
1293 | our $HAVE_ASYNC_INTERRUPT; |
1293 | our $HAVE_ASYNC_INTERRUPT; |
|
|
1294 | |
|
|
1295 | sub _have_async_interrupt() { |
|
|
1296 | $HAVE_ASYNC_INTERRUPT = 1*(!$ENV{PERL_ANYEVENT_AVOID_ASYNC_INTERRUPT} |
|
|
1297 | && eval "use Async::Interrupt 1.0 (); 1") |
|
|
1298 | unless defined $HAVE_ASYNC_INTERRUPT; |
|
|
1299 | |
|
|
1300 | $HAVE_ASYNC_INTERRUPT |
|
|
1301 | } |
|
|
1302 | |
1294 | our ($SIGPIPE_R, $SIGPIPE_W, %SIG_CB, %SIG_EV, $SIG_IO); |
1303 | our ($SIGPIPE_R, $SIGPIPE_W, %SIG_CB, %SIG_EV, $SIG_IO); |
1295 | our (%SIG_ASY, %SIG_ASY_W); |
1304 | our (%SIG_ASY, %SIG_ASY_W); |
1296 | our ($SIG_COUNT, $SIG_TW); |
1305 | our ($SIG_COUNT, $SIG_TW); |
1297 | |
1306 | |
1298 | sub _signal_exec { |
1307 | sub _signal_exec { |
… | |
… | |
1306 | $_->() for values %{ $SIG_CB{$_} || {} }; |
1315 | $_->() for values %{ $SIG_CB{$_} || {} }; |
1307 | } |
1316 | } |
1308 | } |
1317 | } |
1309 | } |
1318 | } |
1310 | |
1319 | |
1311 | # install a dumym wakeupw atcher to reduce signal catching latency |
1320 | # install a dummy wakeup watcher to reduce signal catching latency |
1312 | sub _sig_add() { |
1321 | sub _sig_add() { |
1313 | unless ($SIG_COUNT++) { |
1322 | unless ($SIG_COUNT++) { |
1314 | # try to align timer on a full-second boundary, if possible |
1323 | # try to align timer on a full-second boundary, if possible |
1315 | my $NOW = AnyEvent->now; |
1324 | my $NOW = AnyEvent->now; |
1316 | |
1325 | |
… | |
… | |
1325 | sub _sig_del { |
1334 | sub _sig_del { |
1326 | undef $SIG_TW |
1335 | undef $SIG_TW |
1327 | unless --$SIG_COUNT; |
1336 | unless --$SIG_COUNT; |
1328 | } |
1337 | } |
1329 | |
1338 | |
|
|
1339 | our $_sig_name_init; $_sig_name_init = sub { |
|
|
1340 | eval q{ # poor man's autoloading |
|
|
1341 | undef $_sig_name_init; |
|
|
1342 | |
|
|
1343 | if (_have_async_interrupt) { |
|
|
1344 | *sig2num = \&Async::Interrupt::sig2num; |
|
|
1345 | *sig2name = \&Async::Interrupt::sig2name; |
|
|
1346 | } else { |
|
|
1347 | require Config; |
|
|
1348 | |
|
|
1349 | my %signame2num; |
|
|
1350 | @signame2num{ split ' ', $Config::Config{sig_name} } |
|
|
1351 | = split ' ', $Config::Config{sig_num}; |
|
|
1352 | |
|
|
1353 | my @signum2name; |
|
|
1354 | @signum2name[values %signame2num] = keys %signame2num; |
|
|
1355 | |
|
|
1356 | *sig2num = sub($) { |
|
|
1357 | $_[0] > 0 ? shift : $signame2num{+shift} |
|
|
1358 | }; |
|
|
1359 | *sig2name = sub ($) { |
|
|
1360 | $_[0] > 0 ? $signum2name[+shift] : shift |
|
|
1361 | }; |
|
|
1362 | } |
|
|
1363 | }; |
|
|
1364 | die if $@; |
|
|
1365 | }; |
|
|
1366 | |
|
|
1367 | sub sig2num ($) { &$_sig_name_init; &sig2num } |
|
|
1368 | sub sig2name($) { &$_sig_name_init; &sig2name } |
|
|
1369 | |
1330 | sub _signal { |
1370 | sub 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 { |
1331 | my (undef, %arg) = @_; |
1407 | my (undef, %arg) = @_; |
1332 | |
1408 | |
1333 | my $signal = uc $arg{signal} |
1409 | my $signal = uc $arg{signal} |
1334 | or Carp::croak "required option 'signal' is missing"; |
1410 | or Carp::croak "required option 'signal' is missing"; |
1335 | |
1411 | |
1336 | $SIG_CB{$signal}{$arg{cb}} = $arg{cb}; |
|
|
1337 | |
|
|
1338 | if ($HAVE_ASYNC_INTERRUPT) { |
1412 | if ($HAVE_ASYNC_INTERRUPT) { |
1339 | # async::interrupt |
1413 | # async::interrupt |
1340 | |
1414 | |
1341 | $SIG_ASY{$signal} ||= do { |
1415 | $signal = sig2num $signal; |
1342 | my $asy = new Async::Interrupt |
1416 | $SIG_CB{$signal}{$arg{cb}} = $arg{cb}; |
|
|
1417 | |
|
|
1418 | $SIG_ASY{$signal} ||= new Async::Interrupt |
1343 | cb => sub { undef $SIG_EV{$signal} }, |
1419 | cb => sub { undef $SIG_EV{$signal} }, |
1344 | signal => $signal, |
1420 | signal => $signal, |
1345 | pipe => [$SIGPIPE_R->filenos], |
1421 | pipe => [$SIGPIPE_R->filenos], |
|
|
1422 | pipe_autodrain => 0, |
|
|
1423 | ; |
|
|
1424 | |
|
|
1425 | } else { |
|
|
1426 | # pure perl |
|
|
1427 | |
|
|
1428 | # AE::Util has been loaded in signal |
|
|
1429 | $signal = sig2name $signal; |
|
|
1430 | $SIG_CB{$signal}{$arg{cb}} = $arg{cb}; |
|
|
1431 | |
|
|
1432 | $SIG{$signal} ||= sub { |
|
|
1433 | local $!; |
|
|
1434 | syswrite $SIGPIPE_W, "\x00", 1 unless %SIG_EV; |
|
|
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; |
1346 | ; |
1441 | } |
1347 | $asy->pipe_autodrain (0); |
|
|
1348 | |
1442 | |
1349 | $asy |
1443 | bless [$signal, $arg{cb}], "AnyEvent::Base::signal" |
1350 | }; |
1444 | }; |
1351 | |
1445 | |
1352 | } else { |
1446 | *AnyEvent::Base::signal::DESTROY = sub { |
1353 | # pure perl |
1447 | my ($signal, $cb) = @{$_[0]}; |
1354 | |
1448 | |
1355 | $SIG{$signal} ||= sub { |
1449 | _sig_del; |
1356 | local $!; |
1450 | |
1357 | syswrite $SIGPIPE_W, "\x00", 1 unless %SIG_EV; |
1451 | delete $SIG_CB{$signal}{$cb}; |
|
|
1452 | |
|
|
1453 | $HAVE_ASYNC_INTERRUPT |
|
|
1454 | ? delete $SIG_ASY{$signal} |
|
|
1455 | : # delete doesn't work with older perls - they then |
|
|
1456 | # print weird messages, or just unconditionally exit |
|
|
1457 | # instead of getting the default action. |
1358 | undef $SIG_EV{$signal}; |
1458 | undef $SIG{$signal} |
|
|
1459 | unless keys %{ $SIG_CB{$signal} }; |
1359 | }; |
1460 | }; |
1360 | |
|
|
1361 | # can't do signal processing without introducing races in pure perl, |
|
|
1362 | # so limit the signal latency. |
|
|
1363 | _sig_add; |
|
|
1364 | } |
1461 | }; |
1365 | |
1462 | die if $@; |
1366 | bless [$signal, $arg{cb}], "AnyEvent::Base::signal" |
|
|
1367 | } |
|
|
1368 | |
|
|
1369 | sub signal { |
|
|
1370 | # probe for availability of Async::Interrupt |
|
|
1371 | if (!$ENV{PERL_ANYEVENT_AVOID_ASYNC_INTERRUPT} && eval "use Async::Interrupt 0.6 (); 1") { |
|
|
1372 | warn "AnyEvent: using Async::Interrupt for race-free signal handling.\n" if $VERBOSE >= 8; |
|
|
1373 | |
|
|
1374 | $HAVE_ASYNC_INTERRUPT = 1; |
|
|
1375 | $SIGPIPE_R = new Async::Interrupt::EventPipe; |
|
|
1376 | $SIG_IO = AnyEvent->io (fh => $SIGPIPE_R->fileno, poll => "r", cb => \&_signal_exec); |
|
|
1377 | |
|
|
1378 | } else { |
|
|
1379 | warn "AnyEvent: using emulated perl signal handling with latency timer.\n" if $VERBOSE >= 8; |
|
|
1380 | |
|
|
1381 | require Fcntl; |
|
|
1382 | |
|
|
1383 | if (AnyEvent::WIN32) { |
|
|
1384 | require AnyEvent::Util; |
|
|
1385 | |
|
|
1386 | ($SIGPIPE_R, $SIGPIPE_W) = AnyEvent::Util::portable_pipe (); |
|
|
1387 | AnyEvent::Util::fh_nonblocking ($SIGPIPE_R) if $SIGPIPE_R; |
|
|
1388 | AnyEvent::Util::fh_nonblocking ($SIGPIPE_W) if $SIGPIPE_W; # just in case |
|
|
1389 | } else { |
|
|
1390 | pipe $SIGPIPE_R, $SIGPIPE_W; |
|
|
1391 | fcntl $SIGPIPE_R, &Fcntl::F_SETFL, &Fcntl::O_NONBLOCK if $SIGPIPE_R; |
|
|
1392 | fcntl $SIGPIPE_W, &Fcntl::F_SETFL, &Fcntl::O_NONBLOCK if $SIGPIPE_W; # just in case |
|
|
1393 | |
|
|
1394 | # not strictly required, as $^F is normally 2, but let's make sure... |
|
|
1395 | fcntl $SIGPIPE_R, &Fcntl::F_SETFD, &Fcntl::FD_CLOEXEC; |
|
|
1396 | fcntl $SIGPIPE_W, &Fcntl::F_SETFD, &Fcntl::FD_CLOEXEC; |
|
|
1397 | } |
|
|
1398 | |
|
|
1399 | $SIGPIPE_R |
|
|
1400 | or Carp::croak "AnyEvent: unable to create a signal reporting pipe: $!\n"; |
|
|
1401 | |
|
|
1402 | $SIG_IO = AnyEvent->io (fh => $SIGPIPE_R, poll => "r", cb => \&_signal_exec); |
|
|
1403 | } |
|
|
1404 | |
|
|
1405 | *signal = \&_signal; |
|
|
1406 | &signal |
1463 | &signal |
1407 | } |
|
|
1408 | |
|
|
1409 | sub AnyEvent::Base::signal::DESTROY { |
|
|
1410 | my ($signal, $cb) = @{$_[0]}; |
|
|
1411 | |
|
|
1412 | _sig_del; |
|
|
1413 | |
|
|
1414 | delete $SIG_CB{$signal}{$cb}; |
|
|
1415 | |
|
|
1416 | $HAVE_ASYNC_INTERRUPT |
|
|
1417 | ? delete $SIG_ASY{$signal} |
|
|
1418 | : # delete doesn't work with older perls - they then |
|
|
1419 | # print weird messages, or just unconditionally exit |
|
|
1420 | # instead of getting the default action. |
|
|
1421 | undef $SIG{$signal} |
|
|
1422 | unless keys %{ $SIG_CB{$signal} }; |
|
|
1423 | } |
1464 | } |
1424 | |
1465 | |
1425 | # default implementation for ->child |
1466 | # default implementation for ->child |
1426 | |
1467 | |
1427 | our %PID_CB; |
1468 | our %PID_CB; |