← Index
NYTProf Performance Profile   « block view • line view • sub view »
For mojo-test.pl
  Run on Sat Feb 5 19:54:22 2011
Reported on Sat Feb 5 19:54:56 2011

Filename/Users/marcus/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Mojo/IOLoop.pm
StatementsExecuted 300739 statements in 587ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
249911181ms21.3sMojo::IOLoop::::one_tickMojo::IOLoop::one_tick
10001175.8ms327msMojo::IOLoop::::_acceptMojo::IOLoop::_accept
24991148.0ms182msMojo::IOLoop::::_prepare_connectionsMojo::IOLoop::_prepare_connections
24991142.8ms69.4msMojo::IOLoop::::_prepare_listenMojo::IOLoop::_prepare_listen
10012136.3ms82.2msMojo::IOLoop::::_drop_immediatelyMojo::IOLoop::_drop_immediately
20002127.7ms41.7msMojo::IOLoop::::_not_writingMojo::IOLoop::_not_writing
20001126.6ms8.04sMojo::IOLoop::::_readMojo::IOLoop::_read
10001126.2ms76.7msMojo::IOLoop::::_writeMojo::IOLoop::_write
30003124.2ms7.73sMojo::IOLoop::::_run_eventMojo::IOLoop::_run_event
10011120.2ms20.2msMojo::IOLoop::::CORE:closeMojo::IOLoop::CORE:close (opcode)
69994116.3ms16.6msMojo::IOLoop::::_prepare_loopMojo::IOLoop::_prepare_loop
10001116.0ms76.9msMojo::IOLoop::::local_infoMojo::IOLoop::local_info
24981114.4ms14.4msMojo::IOLoop::::_timerMojo::IOLoop::_timer
10001113.7ms60.6msMojo::IOLoop::::remote_infoMojo::IOLoop::remote_info
10001113.1ms121msMojo::IOLoop::::_hupMojo::IOLoop::_hup
10001112.6ms89.3msMojo::IOLoop::::writeMojo::IOLoop::write
11111.2ms21.3sMojo::IOLoop::::startMojo::IOLoop::start
3000319.83ms9.83msMojo::IOLoop::::_add_eventMojo::IOLoop::_add_event
1000116.09ms6.09msMojo::IOLoop::::connection_timeoutMojo::IOLoop::connection_timeout
1000115.54ms10.6msMojo::IOLoop::::on_errorMojo::IOLoop::on_error
1001215.37ms5.54msMojo::IOLoop::::dropMojo::IOLoop::drop
1015515.01ms5.01msMojo::IOLoop::::CORE:matchMojo::IOLoop::CORE:match (opcode)
1000114.29ms6.60msMojo::IOLoop::::on_readMojo::IOLoop::on_read
1000114.17ms4.17msMojo::IOLoop::::CORE:ssockoptMojo::IOLoop::CORE:ssockopt (opcode)
1000113.89ms6.33msMojo::IOLoop::::on_hupMojo::IOLoop::on_hup
2001213.78ms3.78msMojo::IOLoop::::__ANON__[:137]Mojo::IOLoop::__ANON__[:137]
1113.76ms10.5msMojo::IOLoop::::BEGIN@9Mojo::IOLoop::BEGIN@9
1111.90ms6.74msMojo::IOLoop::::BEGIN@11Mojo::IOLoop::BEGIN@11
1111.62ms1.92msMojo::IOLoop::::BEGIN@5Mojo::IOLoop::BEGIN@5
111691µs798µsMojo::IOLoop::::BEGIN@8Mojo::IOLoop::BEGIN@8
111588µs1.59msMojo::IOLoop::::BEGIN@14Mojo::IOLoop::BEGIN@14
11177µs520µsMojo::IOLoop::::listenMojo::IOLoop::listen
11143µs14.5msMojo::IOLoop::::BEGIN@43Mojo::IOLoop::BEGIN@43
11142µs148µsMojo::IOLoop::::BEGIN@33Mojo::IOLoop::BEGIN@33
11139µs44µsMojo::IOLoop::::newMojo::IOLoop::new
11138µs177µsMojo::IOLoop::::BEGIN@24Mojo::IOLoop::BEGIN@24
11133µs94µsMojo::IOLoop::::BEGIN@20Mojo::IOLoop::BEGIN@20
11129µs29µsMojo::IOLoop::::CORE:ftereadMojo::IOLoop::CORE:fteread (opcode)
11126µs26µsMojo::IOLoop::::CORE:regcompMojo::IOLoop::CORE:regcomp (opcode)
11115µs151µsMojo::IOLoop::::BEGIN@7Mojo::IOLoop::BEGIN@7
11114µs14µsMojo::IOLoop::::CORE:readlineMojo::IOLoop::CORE:readline (opcode)
11114µs80µsMojo::IOLoop::::BEGIN@12Mojo::IOLoop::BEGIN@12
11113µs48µsMojo::IOLoop::::BEGIN@2Mojo::IOLoop::BEGIN@2
22213µs13µsMojo::IOLoop::::__ANON__[:138]Mojo::IOLoop::__ANON__[:138]
11113µs39µsMojo::IOLoop::::BEGIN@50Mojo::IOLoop::BEGIN@50
11112µs58µsMojo::IOLoop::::BEGIN@10Mojo::IOLoop::BEGIN@10
11111µs40µsMojo::IOLoop::::BEGIN@27Mojo::IOLoop::BEGIN@27
11110µs37µsMojo::IOLoop::::BEGIN@28Mojo::IOLoop::BEGIN@28
11110µs36µsMojo::IOLoop::::BEGIN@29Mojo::IOLoop::BEGIN@29
11110µs35µsMojo::IOLoop::::BEGIN@38Mojo::IOLoop::BEGIN@38
11110µs35µsMojo::IOLoop::::BEGIN@37Mojo::IOLoop::BEGIN@37
11110µs36µsMojo::IOLoop::::BEGIN@21Mojo::IOLoop::BEGIN@21
11110µs35µsMojo::IOLoop::::BEGIN@36Mojo::IOLoop::BEGIN@36
1119µs41µsMojo::IOLoop::::BEGIN@40Mojo::IOLoop::BEGIN@40
1119µs35µsMojo::IOLoop::::BEGIN@39Mojo::IOLoop::BEGIN@39
1119µs34µsMojo::IOLoop::::BEGIN@30Mojo::IOLoop::BEGIN@30
1119µs57µsMojo::IOLoop::::BEGIN@17Mojo::IOLoop::BEGIN@17
1119µs36µsMojo::IOLoop::::BEGIN@80Mojo::IOLoop::BEGIN@80
1118µs52µsMojo::IOLoop::::singletonMojo::IOLoop::singleton
1118µs336µsMojo::IOLoop::::BEGIN@13Mojo::IOLoop::BEGIN@13
1117µs33µsMojo::IOLoop::::BEGIN@47Mojo::IOLoop::BEGIN@47
1117µs34µsMojo::IOLoop::::BEGIN@46Mojo::IOLoop::BEGIN@46
1117µs7µsMojo::IOLoop::::BEGIN@6Mojo::IOLoop::BEGIN@6
1116µs32µsMojo::IOLoop::::BEGIN@54Mojo::IOLoop::BEGIN@54
1116µs38µsMojo::IOLoop::::BEGIN@4Mojo::IOLoop::BEGIN@4
0000s0sMojo::IOLoop::::DESTROYMojo::IOLoop::DESTROY
0000s0sMojo::IOLoop::::__ANON__[:133]Mojo::IOLoop::__ANON__[:133]
0000s0sMojo::IOLoop::::__ANON__[:212]Mojo::IOLoop::__ANON__[:212]
0000s0sMojo::IOLoop::::__ANON__[:409]Mojo::IOLoop::__ANON__[:409]
0000s0sMojo::IOLoop::::__ANON__[:419]Mojo::IOLoop::__ANON__[:419]
0000s0sMojo::IOLoop::::__ANON__[:429]Mojo::IOLoop::__ANON__[:429]
0000s0sMojo::IOLoop::::__ANON__[:434]Mojo::IOLoop::__ANON__[:434]
0000s0sMojo::IOLoop::::__ANON__[:436]Mojo::IOLoop::__ANON__[:436]
0000s0sMojo::IOLoop::::__ANON__[:597]Mojo::IOLoop::__ANON__[:597]
0000s0sMojo::IOLoop::::__ANON__[:645]Mojo::IOLoop::__ANON__[:645]
0000s0sMojo::IOLoop::::__ANON__[:654]Mojo::IOLoop::__ANON__[:654]
0000s0sMojo::IOLoop::::__ANON__[:701]Mojo::IOLoop::__ANON__[:701]
0000s0sMojo::IOLoop::::__ANON__[:715]Mojo::IOLoop::__ANON__[:715]
0000s0sMojo::IOLoop::::__ANON__[:754]Mojo::IOLoop::__ANON__[:754]
0000s0sMojo::IOLoop::::__ANON__[:867]Mojo::IOLoop::__ANON__[:867]
0000s0sMojo::IOLoop::::__ANON__[:983]Mojo::IOLoop::__ANON__[:983]
0000s0sMojo::IOLoop::::_add_loop_eventMojo::IOLoop::_add_loop_event
0000s0sMojo::IOLoop::::_connectMojo::IOLoop::_connect
0000s0sMojo::IOLoop::::_errorMojo::IOLoop::_error
0000s0sMojo::IOLoop::::_parse_answerMojo::IOLoop::_parse_answer
0000s0sMojo::IOLoop::::_parse_nameMojo::IOLoop::_parse_name
0000s0sMojo::IOLoop::::_prepare_certMojo::IOLoop::_prepare_cert
0000s0sMojo::IOLoop::::_prepare_keyMojo::IOLoop::_prepare_key
0000s0sMojo::IOLoop::::_run_callbackMojo::IOLoop::_run_callback
0000s0sMojo::IOLoop::::_tls_acceptMojo::IOLoop::_tls_accept
0000s0sMojo::IOLoop::::_tls_connectMojo::IOLoop::_tls_connect
0000s0sMojo::IOLoop::::_tls_errorMojo::IOLoop::_tls_error
0000s0sMojo::IOLoop::::_writingMojo::IOLoop::_writing
0000s0sMojo::IOLoop::::connectMojo::IOLoop::connect
0000s0sMojo::IOLoop::::generate_portMojo::IOLoop::generate_port
0000s0sMojo::IOLoop::::handleMojo::IOLoop::handle
0000s0sMojo::IOLoop::::is_runningMojo::IOLoop::is_running
0000s0sMojo::IOLoop::::lookupMojo::IOLoop::lookup
0000s0sMojo::IOLoop::::on_idleMojo::IOLoop::on_idle
0000s0sMojo::IOLoop::::on_tickMojo::IOLoop::on_tick
0000s0sMojo::IOLoop::::resolveMojo::IOLoop::resolve
0000s0sMojo::IOLoop::::start_tlsMojo::IOLoop::start_tls
0000s0sMojo::IOLoop::::stopMojo::IOLoop::stop
0000s0sMojo::IOLoop::::testMojo::IOLoop::test
0000s0sMojo::IOLoop::::timerMojo::IOLoop::timer
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package Mojo::IOLoop;
2326µs248µs
# spent 48µs (13+34) within Mojo::IOLoop::BEGIN@2 which was called: # once (13µs+34µs) by Mojo::Client::BEGIN@10 at line 2
use Mojo::Base -base;
# spent 48µs making 1 call to Mojo::IOLoop::BEGIN@2 # spent 34µs making 1 call to Mojo::Base::import, recursion: max depth 2, sum of overlapping time 34µs
3
4329µs270µs
# spent 38µs (6+32) within Mojo::IOLoop::BEGIN@4 which was called: # once (6µs+32µs) by Mojo::Client::BEGIN@10 at line 4
use Carp 'croak';
# spent 38µs making 1 call to Mojo::IOLoop::BEGIN@4 # spent 32µs making 1 call to Exporter::import
53263µs22.12ms
# spent 1.92ms (1.62+294µs) within Mojo::IOLoop::BEGIN@5 which was called: # once (1.62ms+294µs) by Mojo::Client::BEGIN@10 at line 5
use Errno qw/EAGAIN ECONNRESET EWOULDBLOCK/;
# spent 1.92ms making 1 call to Mojo::IOLoop::BEGIN@5 # spent 209µs making 1 call to Exporter::import
6323µs17µs
# spent 7µs within Mojo::IOLoop::BEGIN@6 which was called: # once (7µs+0s) by Mojo::Client::BEGIN@10 at line 6
use File::Spec;
# spent 7µs making 1 call to Mojo::IOLoop::BEGIN@6
7331µs2288µs
# spent 151µs (15+136) within Mojo::IOLoop::BEGIN@7 which was called: # once (15µs+136µs) by Mojo::Client::BEGIN@10 at line 7
use IO::File;
# spent 151µs making 1 call to Mojo::IOLoop::BEGIN@7 # spent 136µs making 1 call to Exporter::import
83158µs2858µs
# spent 798µs (691+107) within Mojo::IOLoop::BEGIN@8 which was called: # once (691µs+107µs) by Mojo::Client::BEGIN@10 at line 8
use IO::Poll qw/POLLERR POLLHUP POLLIN POLLOUT/;
# spent 798µs making 1 call to Mojo::IOLoop::BEGIN@8 # spent 60µs making 1 call to Exporter::import
93147µs211.1ms
# spent 10.5ms (3.76+6.69) within Mojo::IOLoop::BEGIN@9 which was called: # once (3.76ms+6.69ms) by Mojo::Client::BEGIN@10 at line 9
use IO::Socket;
# spent 10.5ms making 1 call to Mojo::IOLoop::BEGIN@9 # spent 653µs making 1 call to IO::Socket::import
10327µs2103µs
# spent 58µs (12+46) within Mojo::IOLoop::BEGIN@10 which was called: # once (12µs+46µs) by Mojo::Client::BEGIN@10 at line 10
use List::Util 'first';
# spent 58µs making 1 call to Mojo::IOLoop::BEGIN@10 # spent 46µs making 1 call to Exporter::import
113163µs56.74ms
# spent 6.74ms (1.90+4.85) within Mojo::IOLoop::BEGIN@11 which was called: # once (1.90ms+4.85ms) by Mojo::Client::BEGIN@10 at line 11
use Mojo::URL;
# spent 6.74ms making 1 call to Mojo::IOLoop::BEGIN@11 # spent 3µs making 3 calls to Regexp::DESTROY, avg 867ns/call # spent 3µs making 1 call to Mojo::Base::import, recursion: max depth 2, sum of overlapping time 3µs
12334µs2147µs
# spent 80µs (14+67) within Mojo::IOLoop::BEGIN@12 which was called: # once (14µs+67µs) by Mojo::Client::BEGIN@10 at line 12
use Scalar::Util 'weaken';
# spent 80µs making 1 call to Mojo::IOLoop::BEGIN@12 # spent 67µs making 1 call to Exporter::import
13326µs2664µs
# spent 336µs (8+328) within Mojo::IOLoop::BEGIN@13 which was called: # once (8µs+328µs) by Mojo::Client::BEGIN@10 at line 13
use Socket qw/IPPROTO_TCP TCP_NODELAY/;
# spent 336µs making 1 call to Mojo::IOLoop::BEGIN@13 # spent 328µs making 1 call to Exporter::import
143170µs21.78ms
# spent 1.59ms (588µs+1.00) within Mojo::IOLoop::BEGIN@14 which was called: # once (588µs+1.00ms) by Mojo::Client::BEGIN@10 at line 14
use Time::HiRes 'time';
# spent 1.59ms making 1 call to Mojo::IOLoop::BEGIN@14 # spent 186µs making 1 call to Time::HiRes::import
15
16# Debug
17330µs2105µs
# spent 57µs (9+48) within Mojo::IOLoop::BEGIN@17 which was called: # once (9µs+48µs) by Mojo::Client::BEGIN@10 at line 17
use constant DEBUG => $ENV{MOJO_IOLOOP_DEBUG} || 0;
# spent 57µs making 1 call to Mojo::IOLoop::BEGIN@17 # spent 48µs making 1 call to constant::import
18
19# Perl 5.12 required for "inet_pton"
20355µs2119µs
# spent 94µs (33+61) within Mojo::IOLoop::BEGIN@20 which was called: # once (33µs+61µs) by Mojo::Client::BEGIN@10 at line 20
use constant PTON => eval 'use 5.012000; 1';
# spent 94µs making 1 call to Mojo::IOLoop::BEGIN@20 # spent 25µs making 1 call to constant::import
# spent 39µs executing statements in string eval
# includes 36µs spent executing 1 call to 1 sub defined therein.
21333µs362µs
# spent 36µs (10+26) within Mojo::IOLoop::BEGIN@21 which was called: # once (10µs+26µs) by Mojo::Client::BEGIN@10 at line 21
use constant PTON_AF_INET6 => PTON ? Socket::AF_INET6() : 0;
# spent 36µs making 1 call to Mojo::IOLoop::BEGIN@21 # spent 25µs making 1 call to constant::import # spent 1µs making 1 call to constant::__ANON__[constant.pm:121]
22
23# Epoll support requires IO::Epoll
24124µs
# spent 177µs (38+139) within Mojo::IOLoop::BEGIN@24 which was called: # once (38µs+139µs) by Mojo::Client::BEGIN@10 at line 26
use constant EPOLL => $ENV{MOJO_POLL}
# spent 24µs making 1 call to constant::import
# spent 128µs executing statements in string eval
# includes 115µs spent executing 1 call to 1 sub defined therein.
25 ? 0
26361µs1177µs : eval 'use IO::Epoll 0.02 (); 1';
# spent 177µs making 1 call to Mojo::IOLoop::BEGIN@24
27336µs368µs
# spent 40µs (11+28) within Mojo::IOLoop::BEGIN@27 which was called: # once (11µs+28µs) by Mojo::Client::BEGIN@10 at line 27
use constant EPOLL_POLLERR => EPOLL ? IO::Epoll::POLLERR() : 0;
# spent 40µs making 1 call to Mojo::IOLoop::BEGIN@27 # spent 27µs making 1 call to constant::import # spent 1µs making 1 call to constant::__ANON__[constant.pm:121]
28335µs364µs
# spent 37µs (10+27) within Mojo::IOLoop::BEGIN@28 which was called: # once (10µs+27µs) by Mojo::Client::BEGIN@10 at line 28
use constant EPOLL_POLLHUP => EPOLL ? IO::Epoll::POLLHUP() : 0;
# spent 37µs making 1 call to Mojo::IOLoop::BEGIN@28 # spent 26µs making 1 call to constant::import # spent 900ns making 1 call to constant::__ANON__[constant.pm:121]
29332µs363µs
# spent 36µs (10+26) within Mojo::IOLoop::BEGIN@29 which was called: # once (10µs+26µs) by Mojo::Client::BEGIN@10 at line 29
use constant EPOLL_POLLIN => EPOLL ? IO::Epoll::POLLIN() : 0;
# spent 36µs making 1 call to Mojo::IOLoop::BEGIN@29 # spent 25µs making 1 call to constant::import # spent 900ns making 1 call to constant::__ANON__[constant.pm:121]
30334µs359µs
# spent 34µs (9+25) within Mojo::IOLoop::BEGIN@30 which was called: # once (9µs+25µs) by Mojo::Client::BEGIN@10 at line 30
use constant EPOLL_POLLOUT => EPOLL ? IO::Epoll::POLLOUT() : 0;
# spent 34µs making 1 call to Mojo::IOLoop::BEGIN@30 # spent 24µs making 1 call to constant::import # spent 900ns making 1 call to constant::__ANON__[constant.pm:121]
31
32# KQueue support requires IO::KQueue
33123µs
# spent 148µs (42+106) within Mojo::IOLoop::BEGIN@33 which was called: # once (42µs+106µs) by Mojo::Client::BEGIN@10 at line 35
use constant KQUEUE => $ENV{MOJO_POLL}
# spent 23µs making 1 call to constant::import
# spent 94µs executing statements in string eval
# includes 83µs spent executing 1 call to 1 sub defined therein.
34 ? 0
35361µs1148µs : eval 'use IO::KQueue 0.34 (); 1';
# spent 148µs making 1 call to Mojo::IOLoop::BEGIN@33
36332µs360µs
# spent 35µs (10+25) within Mojo::IOLoop::BEGIN@36 which was called: # once (10µs+25µs) by Mojo::Client::BEGIN@10 at line 36
use constant KQUEUE_ADD => KQUEUE ? IO::KQueue::EV_ADD() : 0;
# spent 35µs making 1 call to Mojo::IOLoop::BEGIN@36 # spent 24µs making 1 call to constant::import # spent 900ns making 1 call to constant::__ANON__[constant.pm:121]
37332µs360µs
# spent 35µs (10+25) within Mojo::IOLoop::BEGIN@37 which was called: # once (10µs+25µs) by Mojo::Client::BEGIN@10 at line 37
use constant KQUEUE_DELETE => KQUEUE ? IO::KQueue::EV_DELETE() : 0;
# spent 35µs making 1 call to Mojo::IOLoop::BEGIN@37 # spent 24µs making 1 call to constant::import # spent 900ns making 1 call to constant::__ANON__[constant.pm:121]
38332µs360µs
# spent 35µs (10+25) within Mojo::IOLoop::BEGIN@38 which was called: # once (10µs+25µs) by Mojo::Client::BEGIN@10 at line 38
use constant KQUEUE_EOF => KQUEUE ? IO::KQueue::EV_EOF() : 0;
# spent 35µs making 1 call to Mojo::IOLoop::BEGIN@38 # spent 24µs making 1 call to constant::import # spent 900ns making 1 call to constant::__ANON__[constant.pm:121]
39332µs361µs
# spent 35µs (9+26) within Mojo::IOLoop::BEGIN@39 which was called: # once (9µs+26µs) by Mojo::Client::BEGIN@10 at line 39
use constant KQUEUE_READ => KQUEUE ? IO::KQueue::EVFILT_READ() : 0;
# spent 35µs making 1 call to Mojo::IOLoop::BEGIN@39 # spent 25µs making 1 call to constant::import # spent 900ns making 1 call to constant::__ANON__[constant.pm:121]
40334µs372µs
# spent 41µs (9+31) within Mojo::IOLoop::BEGIN@40 which was called: # once (9µs+31µs) by Mojo::Client::BEGIN@10 at line 40
use constant KQUEUE_WRITE => KQUEUE ? IO::KQueue::EVFILT_WRITE() : 0;
# spent 41µs making 1 call to Mojo::IOLoop::BEGIN@40 # spent 30µs making 1 call to constant::import # spent 900ns making 1 call to constant::__ANON__[constant.pm:121]
41
42# TLS support requires IO::Socket::SSL
43128µs
# spent 14.5ms (43µs+14.5) within Mojo::IOLoop::BEGIN@43 which was called: # once (43µs+14.5ms) by Mojo::Client::BEGIN@10 at line 45
use constant TLS => $ENV{MOJO_NO_TLS}
# spent 28µs making 1 call to constant::import
# spent 204µs executing statements in string eval
# includes 7.70ms spent executing 1 call to 1 sub defined therein.
44 ? 0
45361µs114.5ms : eval 'use IO::Socket::SSL 1.37 "inet4"; 1';
# spent 14.5ms making 1 call to Mojo::IOLoop::BEGIN@43
46328µs260µs
# spent 34µs (7+27) within Mojo::IOLoop::BEGIN@46 which was called: # once (7µs+27µs) by Mojo::Client::BEGIN@10 at line 46
use constant TLS_READ => TLS ? IO::Socket::SSL::SSL_WANT_READ() : 0;
# spent 34µs making 1 call to Mojo::IOLoop::BEGIN@46 # spent 27µs making 1 call to constant::import
47342µs258µs
# spent 33µs (7+25) within Mojo::IOLoop::BEGIN@47 which was called: # once (7µs+25µs) by Mojo::Client::BEGIN@10 at line 47
use constant TLS_WRITE => TLS ? IO::Socket::SSL::SSL_WANT_WRITE() : 0;
# spent 33µs making 1 call to Mojo::IOLoop::BEGIN@47 # spent 25µs making 1 call to constant::import
48
49# Windows
50356µs365µs
# spent 39µs (13+26) within Mojo::IOLoop::BEGIN@50 which was called: # once (13µs+26µs) by Mojo::Client::BEGIN@10 at line 50
use constant WINDOWS => $^O eq 'MSWin32' || $^O =~ /cygwin/ ? 1 : 0;
# spent 39µs making 1 call to Mojo::IOLoop::BEGIN@50 # spent 25µs making 1 call to constant::import # spent 900ns making 1 call to Mojo::IOLoop::CORE:match
51
52# Default TLS cert (20.03.2010)
53# (openssl req -new -x509 -keyout cakey.pem -out cacert.pem -nodes -days 7300)
54126µs
# spent 32µs (6+26) within Mojo::IOLoop::BEGIN@54 which was called: # once (6µs+26µs) by Mojo::Client::BEGIN@10 at line 76
use constant CERT => <<EOF;
# spent 26µs making 1 call to constant::import
55-----BEGIN CERTIFICATE-----
56MIIDbzCCAtigAwIBAgIJAM+kFv1MwalmMA0GCSqGSIb3DQEBBQUAMIGCMQswCQYD
57VQQGEwJERTEWMBQGA1UECBMNTmllZGVyc2FjaHNlbjESMBAGA1UEBxMJSGFtYmVy
58Z2VuMRQwEgYDVQQKEwtNb2pvbGljaW91czESMBAGA1UEAxMJbG9jYWxob3N0MR0w
59GwYJKoZIhvcNAQkBFg5rcmFpaEBjcGFuLm9yZzAeFw0xMDAzMjAwMDQ1MDFaFw0z
60MDAzMTUwMDQ1MDFaMIGCMQswCQYDVQQGEwJERTEWMBQGA1UECBMNTmllZGVyc2Fj
61aHNlbjESMBAGA1UEBxMJSGFtYmVyZ2VuMRQwEgYDVQQKEwtNb2pvbGljaW91czES
62MBAGA1UEAxMJbG9jYWxob3N0MR0wGwYJKoZIhvcNAQkBFg5rcmFpaEBjcGFuLm9y
63ZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzu9mOiyUJB2NBuf1lZxViNM2
64VISqRAoaXXGOBa6RgUoVfA/n81RQlgvVA0qCSQHC534DdYRk3CdyJR9UGPuxF8k4
65CckOaHWgcJJsd8H0/q73PjbA5ItIpGTTJNh8WVpFDjHTJmQ5ihwddap4/offJxZD
66dPrMFtw1ZHBRug5tHUECAwEAAaOB6jCB5zAdBgNVHQ4EFgQUo+Re5wuuzVFqH/zV
67cxRGXL0j5K4wgbcGA1UdIwSBrzCBrIAUo+Re5wuuzVFqH/zVcxRGXL0j5K6hgYik
68gYUwgYIxCzAJBgNVBAYTAkRFMRYwFAYDVQQIEw1OaWVkZXJzYWNoc2VuMRIwEAYD
69VQQHEwlIYW1iZXJnZW4xFDASBgNVBAoTC01vam9saWNpb3VzMRIwEAYDVQQDEwls
70b2NhbGhvc3QxHTAbBgkqhkiG9w0BCQEWDmtyYWloQGNwYW4ub3JnggkAz6QW/UzB
71qWYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCZZcOeAobctD9wtPtO
7240CKHpiGYEM3rh7VvBhjTcVnX6XlLvffIg3uTrVRhzmlEQCZz3O5TsBzfMAVnjYz
73llhwgRF6Xn8ict9L8yKDoGSbw0Q7HaCb8/kOe0uKhcSDUd3PjJU0ZWgc20zcGFA9
74R65bABoJ2vU1rlQFmjs0RT4UcQ==
75-----END CERTIFICATE-----
76352µs132µsEOF
# spent 32µs making 1 call to Mojo::IOLoop::BEGIN@54
77
78# Default TLS key (20.03.2010)
79# (openssl req -new -x509 -keyout cakey.pem -out cacert.pem -nodes -days 7300)
80127µs
# spent 36µs (9+27) within Mojo::IOLoop::BEGIN@80 which was called: # once (9µs+27µs) by Mojo::Client::BEGIN@10 at line 96
use constant KEY => <<EOF;
# spent 27µs making 1 call to constant::import
81-----BEGIN RSA PRIVATE KEY-----
82MIICXAIBAAKBgQDO72Y6LJQkHY0G5/WVnFWI0zZUhKpEChpdcY4FrpGBShV8D+fz
83VFCWC9UDSoJJAcLnfgN1hGTcJ3IlH1QY+7EXyTgJyQ5odaBwkmx3wfT+rvc+NsDk
84i0ikZNMk2HxZWkUOMdMmZDmKHB11qnj+h98nFkN0+swW3DVkcFG6Dm0dQQIDAQAB
85AoGAeLmd8C51tqQu1GqbEc+E7zAZsDE9jDhArWdELfhsFvt7kUdOUN1Nrlv0x9i+
86LY2Dgb44kmTM2suAgjvGulSMOYBGosZcM0w3ES76nmeAVJ1NBFhbZTCJqo9svoD/
87NKdctRflUuvFSWimoui+vj9D5p/4lvAMdBHUWj5FlQsYiOECQQD/FRXtsDetptFu
88Vp8Kw+6bZ5+efcjVfciTp7fQKI2xZ2n1QyloaV4zYXgDC2y3fMYuRigCGrX9XeFX
89oGHGMyYFAkEAz635I8f4WQa/wvyl/SR5agtDVnkJqMHMgOuykytiF8NFbDSkJv+b
901VfyrWcfK/PVsSGBI67LCMDoP+PZBVOjDQJBAIInoCjH4aEZnYNPb5duojFpjmiw
91helpZQ7yZTgxeRssSUR8IITGPuq4sSPckHyPjg/OfFuWhYXigTjU/Q7EyoECQERT
92Dykna9wWLVZ/+jgLHOq3Y+L6FSRxBc/QO0LRvgblVlygAPVXmLQaqBtGVuoF4WLS
93DANqSR/LH12Nn2NyPa0CQBbzoHgx2i3RncWoq1EeIg2mSMevEcjA6sxgYmsyyzlv
94AnqxHi90n/p912ynLg2SjBq+03GaECeGzC/QqKK2gtA=
95-----END RSA PRIVATE KEY-----
9635.60ms136µsEOF
# spent 36µs making 1 call to Mojo::IOLoop::BEGIN@80
97
98# DNS server (default to Google Public DNS)
991600nsour $DNS_SERVER = '8.8.8.8';
100
101# Try to detect DNS server
102140µs129µsif (-r '/etc/resolv.conf') {
# spent 29µs making 1 call to Mojo::IOLoop::CORE:fteread
10314µs160µs my $file = IO::File->new;
# spent 60µs making 1 call to IO::File::new
10412µs171µs $file->open('< /etc/resolv.conf');
# spent 71µs making 1 call to IO::File::open
105142µs114µs for my $line (<$file>) {
# spent 14µs making 1 call to Mojo::IOLoop::CORE:readline
1061221µs126µs if ($line =~ /^nameserver\s+(\S+)$/) {
# spent 6µs making 12 calls to Mojo::IOLoop::CORE:match, avg 525ns/call
107
108 # New DNS server
10922µs $DNS_SERVER = $1;
110
111 # Debug
1122200ns warn qq/DETECTED DNS SERVER ($DNS_SERVER)\n/ if DEBUG;
113 }
114 }
115}
116
117# DNS record types
11813µsmy $DNS_TYPES = {
119 '*' => 0x00ff,
120 A => 0x0001,
121 AAAA => 0x001c,
122 CNAME => 0x0005,
123 MX => 0x000f,
124 NS => 0x0002,
125 PTR => 0x000c,
126 TXT => 0x0010
127};
128
129# "localhost"
1301500nsour $LOCALHOST = '127.0.0.1';
131
13214µs1295µshas [qw/accept_timeout connect_timeout dns_timeout/] => 3;
# spent 295µs making 1 call to Mojo::Base::__ANON__[Mojo/Base.pm:38]
13313µs1101µshas dns_server => sub { $ENV{MOJO_DNS_SERVER} || $DNS_SERVER };
# spent 101µs making 1 call to Mojo::Base::__ANON__[Mojo/Base.pm:38]
13412µs193µshas max_accepts => 0;
# spent 93µs making 1 call to Mojo::Base::__ANON__[Mojo/Base.pm:38]
13512µs189µshas max_connections => 1000;
# spent 89µs making 1 call to Mojo::Base::__ANON__[Mojo/Base.pm:38]
136
# spent 13µs within Mojo::IOLoop::__ANON__[/Users/marcus/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Mojo/IOLoop.pm:138] which was called 2 times, avg 7µs/call: # once (8µs+0s) by Mojo::Base::__ANON__[(eval 61)[/Users/marcus/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Mojo/Base.pm:123]:8] at line 4 of (eval 61)[Mojo/Base.pm:123] # once (5µs+0s) by Mojo::Base::__ANON__[(eval 60)[/Users/marcus/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Mojo/Base.pm:123]:8] at line 4 of (eval 60)[Mojo/Base.pm:123]
has [qw/on_lock on_unlock/] => sub {
13720014.69ms
# spent 3.78ms within Mojo::IOLoop::__ANON__[/Users/marcus/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Mojo/IOLoop.pm:137] which was called 2001 times, avg 2µs/call: # 1001 times (1.53ms+0s) by Mojo::IOLoop::_prepare_listen at line 1304, avg 2µs/call # 1000 times (2.25ms+0s) by Mojo::IOLoop::_accept at line 849, avg 2µs/call
sub {1}
138322µs1193µs};
# spent 193µs making 1 call to Mojo::Base::__ANON__[Mojo/Base.pm:38]
13912µs197µshas timeout => '0.025';
# spent 97µs making 1 call to Mojo::Base::__ANON__[Mojo/Base.pm:38]
140
141# Singleton
1421100nsour $LOOP;
143
144sub DESTROY {
145 my $self = shift;
146
147 # Cleanup connections
148 for my $id (keys %{$self->{_cs}}) { $self->_drop_immediately($id) }
149
150 # Cleanup listen sockets
151 for my $id (keys %{$self->{_listen}}) { $self->_drop_immediately($id) }
152
153 # Cleanup temporary cert file
154 if (my $cert = $self->{_cert}) { unlink $cert if -w $cert }
155
156 # Cleanup temporary key file
157 if (my $key = $self->{_key}) { unlink $key if -w $key }
158}
159
160
# spent 44µs (39+5) within Mojo::IOLoop::new which was called: # once (39µs+5µs) by Mojo::IOLoop::singleton at line 721
sub new {
161637µs my $class = shift;
162
163 # Build new loop from singleton if possible
164 my $loop = $LOOP;
165 local $LOOP = undef;
16615µs my $self = $loop ? $loop->new(@_) : $class->SUPER::new(@_);
# spent 5µs making 1 call to Mojo::Base::new
167
168 # Ignore PIPE signal
169 $SIG{PIPE} = 'IGNORE';
170
171 return $self;
172}
173
174sub connect {
175 my $self = shift;
176
177 # Arguments
178 my $args = ref $_[0] ? $_[0] : {@_};
179
180 # TLS check
181 return if $args->{tls} && !TLS;
182
183 # Protocol
184 $args->{proto} ||= 'tcp';
185
186 # Connection
187 my $c = {
188 buffer => '',
189 on_connect => $args->{on_connect},
190 connecting => 1,
191 tls => $args->{tls},
192 tls_cert => $args->{tls_cert},
193 tls_key => $args->{tls_key}
194 };
195 (my $id) = "$c" =~ /0x([\da-f]+)/;
196 $self->{_cs}->{$id} = $c;
197
198 # Register callbacks
199 for my $name (qw/error hup read/) {
200 my $cb = $args->{"on_$name"};
201 my $event = "on_$name";
202 $self->$event($id => $cb) if $cb;
203 }
204
205 # Lookup
206 if (!$args->{handle} && (my $address = $args->{address})) {
207 $self->lookup(
208 $address => sub {
209 my $self = shift;
210 $args->{address} = shift || $args->{address};
211 $self->_connect($id, $args);
212 }
213 );
214 }
215
216 # Connect
217 else { $self->_connect($id, $args) }
218
219 return $id;
220}
221
222
# spent 6.09ms within Mojo::IOLoop::connection_timeout which was called 1000 times, avg 6µs/call: # 1000 times (6.09ms+0s) by Mojo::Server::Daemon::__ANON__[/Users/marcus/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Mojo/Server/Daemon.pm:293] at line 292 of Mojo/Server/Daemon.pm, avg 6µs/call
sub connection_timeout {
22330006.37ms my ($self, $id, $timeout) = @_;
224
225 # Connection
226 return unless my $c = $self->{_cs}->{$id};
227
228 # Timeout
229 $c->{timeout} = $timeout and return $self if $timeout;
230
231 return $c->{timeout};
232}
233
234
# spent 5.54ms (5.37+171µs) within Mojo::IOLoop::drop which was called 1001 times, avg 6µs/call: # 1000 times (5.35ms+0s) by Mojo::Server::Daemon::_finish at line 237 of Mojo/Server/Daemon.pm, avg 5µs/call # once (17µs+171µs) by Mojo::Server::Daemon::DESTROY at line 51 of Mojo/Server/Daemon.pm
sub drop {
23520035.30ms my ($self, $id) = @_;
236
237 # Drop connection gracefully
238 if (my $c = $self->{_cs}->{$id}) { return $c->{finish} = 1 }
239
240 # Drop
2411171µs return $self->_drop_immediately($id);
# spent 171µs making 1 call to Mojo::IOLoop::_drop_immediately
242}
243
244sub generate_port {
245 my $self = shift;
246
247 # Ports
248 my $port = 1 . int(rand 10) . int(rand 10) . int(rand 10) . int(rand 10);
249 while ($port++ < 30000) {
250
251 # Try port
252 return $port
253 if IO::Socket::INET->new(
254 Listen => 5,
255 LocalAddr => '127.0.0.1',
256 LocalPort => $port,
257 Proto => 'tcp'
258 );
259 }
260
261 # Nothing
262 return;
263}
264
265sub is_running { shift->{_running} }
266
267# "Fat Tony is a cancer on this fair city!
268# He is the cancer and I am the… uh… what cures cancer?"
269
# spent 520µs (77+443) within Mojo::IOLoop::listen which was called: # once (77µs+443µs) by Mojo::Server::Daemon::_listen at line 299 of Mojo/Server/Daemon.pm
sub listen {
27031102µs my $self = shift;
271
272 # Arguments
273 my $args = ref $_[0] ? $_[0] : {@_};
274
275 # TLS check
276 croak "IO::Socket::SSL 1.37 required for TLS support"
277 if $args->{tls} && !TLS;
278
279 # Options
280 my %options = (
281 Listen => $args->{backlog} || SOMAXCONN,
282 Proto => 'tcp',
283 Type => SOCK_STREAM,
284 %{$args->{args} || {}}
285 );
286
287 # File
288 my $file = $args->{file};
289
290 # Port
291 my $port = $args->{port} || 3000;
292
293 # File descriptor reuse
294 my $reuse = defined $file ? $file : $port;
295 $ENV{MOJO_REUSE} ||= '';
296 my $fd;
297226µs if ($ENV{MOJO_REUSE} =~ /(?:^|\,)$reuse\:(\d+)/) { $fd = $1 }
# spent 26µs making 1 call to Mojo::IOLoop::CORE:regcomp # spent 200ns making 1 call to Mojo::IOLoop::CORE:match
298
299 # Connection
300 my $c = {
301 file => $args->{file} ? 1 : 0,
302 on_accept => $args->{on_accept},
303 on_error => $args->{on_error},
304 on_hup => $args->{on_hup},
305 on_read => $args->{on_read},
306 };
30713µs (my $id) = "$c" =~ /0x([\da-f]+)/;
# spent 3µs making 1 call to Mojo::IOLoop::CORE:match
308 $self->{_listen}->{$id} = $c;
309
310 # Allow file descriptor inheritance
311 local $^F = 1000;
312
313 # Listen on UNIX domain socket
314 my $socket;
315 if (defined $file) {
316
317 # Path
318 $options{Local} = $file;
319
320 # Create socket
321 $socket =
322 defined $fd
323 ? IO::Socket::UNIX->new
324 : IO::Socket::UNIX->new(%options)
325 or croak "Can't create listen socket: $!";
326 }
327
328 # Listen on port
329 else {
330
331 # Socket options
332 $options{LocalAddr} = $args->{address} || '0.0.0.0';
333 $options{LocalPort} = $port;
334 $options{Proto} = 'tcp';
335 $options{ReuseAddr} = 1;
336
337 # Create socket
3381407µs $socket =
# spent 407µs making 1 call to IO::Socket::INET::new
339 defined $fd
340 ? IO::Socket::INET->new
341 : IO::Socket::INET->new(%options)
342 or croak "Can't create listen socket: $!";
343 }
344
345 # File descriptor
346 if (defined $fd) {
347 $socket->fdopen($fd, 'r')
348 or croak "Can't open file descriptor $fd: $!";
349 }
350 else {
351 $fd = fileno $socket;
352 $reuse = ",$reuse" if length $ENV{MOJO_REUSE};
353 $ENV{MOJO_REUSE} .= "$reuse:$fd";
354 }
355 $self->{_fds}->{$fd} = $id;
356
357 # Socket
358 $c->{handle} = $socket;
359 $self->{_reverse}->{$socket} = $id;
360
361 # TLS
362 if ($args->{tls}) {
363
364 # Defaults
365 my %options = (
366 SSL_startHandshake => 0,
367 SSL_cert_file => $args->{tls_cert} || $self->_prepare_cert,
368 SSL_key_file => $args->{tls_key} || $self->_prepare_key,
369 );
370
371 # Client certificate verification
372 %options = (
373 SSL_verify_callback => $args->{tls_verify},
374 SSL_ca_file => -T $args->{tls_ca} ? $args->{tls_ca} : undef,
375 SSL_ca_path => -d $args->{tls_ca} ? $args->{tls_ca} : undef,
376 SSL_verify_mode => $args->{tls_ca} ? 0x03 : undef,
377 %options
378 ) if $args->{tls_ca};
379
380 $c->{tls} = {%options, %{$args->{tls_args} || {}}};
381 }
382
383 # Accept limit
38416µs $self->{_accepts} = $self->max_accepts if $self->max_accepts;
385
386 return $id;
387}
388
389
# spent 76.9ms (16.0+61.0) within Mojo::IOLoop::local_info which was called 1000 times, avg 77µs/call: # 1000 times (16.0ms+61.0ms) by Mojo::Server::Daemon::_build_tx at line 132 of Mojo/Server/Daemon.pm, avg 77µs/call
sub local_info {
390500017.3ms my ($self, $id) = @_;
391
392 # Connection
393 return {} unless my $c = $self->{_cs}->{$id};
394
395 # Socket
396 return {} unless my $socket = $c->{handle};
397
398 # UNIX domain socket info
39910002.40ms return {path => $socket->hostpath} if $socket->can('hostpath');
# spent 2.40ms making 1000 calls to UNIVERSAL::can, avg 2µs/call
400
401 # Info
402200058.6ms return {address => $socket->sockhost, port => $socket->sockport};
# spent 42.6ms making 1000 calls to IO::Socket::INET::sockhost, avg 43µs/call # spent 16.0ms making 1000 calls to IO::Socket::INET::sockport, avg 16µs/call
403}
404
405sub lookup {
406 my ($self, $name, $cb) = @_;
407
408 # "localhost"
409 return $self->timer(0 => sub { shift->$cb($LOCALHOST) })
410 if $name eq 'localhost';
411
412 # IPv4
413 $self->resolve(
414 $name, 'A',
415 sub {
416 my ($self, $results) = @_;
417
418 # Success
419 my $result = first { $_->[0] eq 'A' } @$results;
420 return $self->$cb($result->[1]) if $result;
421
422 # IPv6
423 $self->resolve(
424 $name, 'AAAA',
425 sub {
426 my ($self, $results) = @_;
427
428 # Success
429 my $result = first { $_->[0] eq 'AAAA' } @$results;
430 return $self->$cb($result->[1]) if $result;
431
432 # Pass through
433 $self->$cb();
434 }
435 );
436 }
437 );
438}
439
44010004.82ms10005.07ms
# spent 10.6ms (5.54+5.07) within Mojo::IOLoop::on_error which was called 1000 times, avg 11µs/call: # 1000 times (5.54ms+5.07ms) by Mojo::IOLoop::_accept at line 889, avg 11µs/call
sub on_error { shift->_add_event('error', @_) }
# spent 5.07ms making 1000 calls to Mojo::IOLoop::_add_event, avg 5µs/call
44110002.80ms10002.45ms
# spent 6.33ms (3.89+2.45) within Mojo::IOLoop::on_hup which was called 1000 times, avg 6µs/call: # 1000 times (3.89ms+2.45ms) by Mojo::IOLoop::_accept at line 889, avg 6µs/call
sub on_hup { shift->_add_event('hup', @_) }
# spent 2.45ms making 1000 calls to Mojo::IOLoop::_add_event, avg 2µs/call
442sub on_idle { shift->_add_loop_event('idle', @_) }
44310003.04ms10002.31ms
# spent 6.60ms (4.29+2.31) within Mojo::IOLoop::on_read which was called 1000 times, avg 7µs/call: # 1000 times (4.29ms+2.31ms) by Mojo::IOLoop::_accept at line 889, avg 7µs/call
sub on_read { shift->_add_event('read', @_) }
# spent 2.31ms making 1000 calls to Mojo::IOLoop::_add_event, avg 2µs/call
444sub on_tick { shift->_add_loop_event('tick', @_) }
445
446
# spent 21.3s (181ms+21.1) within Mojo::IOLoop::one_tick which was called 2499 times, avg 8.53ms/call: # 2499 times (181ms+21.1s) by Mojo::IOLoop::start at line 733, avg 8.53ms/call
sub one_tick {
44769953135ms my ($self, $timeout) = @_;
448
449 # Timeout
450249911.2ms $timeout = $self->timeout unless defined $timeout;
# spent 11.2ms making 2499 calls to Mojo::Base::__ANON__[(eval 62)[Mojo/Base.pm:123]:8], avg 4µs/call
451
452 # Prepare listen sockets
453249969.4ms $self->_prepare_listen;
# spent 69.4ms making 2499 calls to Mojo::IOLoop::_prepare_listen, avg 28µs/call
454
455 # Prepare connections
4562499182ms $self->_prepare_connections;
# spent 182ms making 2499 calls to Mojo::IOLoop::_prepare_connections, avg 73µs/call
457
458 # Loop
45924995.72ms my $loop = $self->_prepare_loop;
# spent 5.72ms making 2499 calls to Mojo::IOLoop::_prepare_loop, avg 2µs/call
460
461 # Reverse map
462 my $r = $self->{_reverse};
463
464 # Events
465 my (@error, @hup, @read, @write);
466
467 # KQueue
46849987.69ms if (KQUEUE) {
# spent 7.69ms making 4998 calls to constant::__ANON__[constant.pm:121], avg 2µs/call
469
470 # Catch interrupted system call errors
471 my @ret;
472 my $success = eval { @ret = $loop->kevent(1000 * $timeout); 1 };
473 die "KQueue error: $@" if !$success && $@;
474
475 # Events
476 for my $kev (@ret) {
477 my ($fd, $filter, $flags, $fflags) = @$kev;
478
479 # Id
480 my $id = $self->{_fds}->{$fd};
481 next unless $id;
482
483 # Error
484 if ($flags == KQUEUE_EOF) {
485 if ($fflags) { push @error, $id }
486 else { push @hup, $id }
487 }
488
489 # Read
490 push @read, $id if $filter == KQUEUE_READ;
491
492 # Write
493 push @write, $id if $filter == KQUEUE_WRITE;
494 }
495 }
496
497 # Epoll
498 elsif (EPOLL) {
499 $loop->poll($timeout);
500
501 # Read
502 push @read, $r->{$_} for $loop->handles(EPOLL_POLLIN);
503
504 # Write
505 push @write, $r->{$_} for $loop->handles(EPOLL_POLLOUT);
506
507 # Error
508 push @error, $r->{$_} for $loop->handles(EPOLL_POLLERR);
509
510 # HUP
511 push @hup, $r->{$_} for $loop->handles(EPOLL_POLLHUP);
512 }
513
514 # Poll
515 else {
516249912.7s $loop->poll($timeout);
# spent 12.7s making 2499 calls to IO::Poll::poll, avg 5.09ms/call
517
518 # Read
519249837.0ms push @read, $r->{$_} for $loop->handles(POLLIN);
# spent 37.0ms making 2498 calls to IO::Poll::handles, avg 15µs/call
520
521 # Write
522249818.0ms push @write, $r->{$_} for $loop->handles(POLLOUT);
# spent 18.0ms making 2498 calls to IO::Poll::handles, avg 7µs/call
523
524 # Error
525249816.4ms push @error, $r->{$_} for $loop->handles(POLLERR);
# spent 16.4ms making 2498 calls to IO::Poll::handles, avg 7µs/call
526
527 # HUP
528249815.7ms push @hup, $r->{$_} for $loop->handles(POLLHUP);
# spent 15.7ms making 2498 calls to IO::Poll::handles, avg 6µs/call
529 }
530
531 # Read
53220008.04s $self->_read($_) for @read;
# spent 8.04s making 2000 calls to Mojo::IOLoop::_read, avg 4.02ms/call
533
534 # Write
535 $self->_write($_) for @write;
536
537 # Error
538 $self->_error($_) for @error;
539
540 # HUP
541 $self->_hup($_) for @hup;
542
543 # Timers
544249814.4ms my $timers = $self->_timer;
# spent 14.4ms making 2498 calls to Mojo::IOLoop::_timer, avg 6µs/call
545
546 # Tick
547 for my $tick (keys %{$self->{_tick}}) {
548 $self->_run_callback('tick', $self->{_tick}->{$tick}->{cb}, $tick);
549 }
550
551 # Idle
552 for my $idle (keys %{$self->{_idle}}) {
553 $self->_run_callback('idle', $self->{_idle}->{$idle}->{cb}, $idle)
554 unless @read || @write || @error || @hup || $timers;
555 }
556}
557
558sub handle {
559 my ($self, $id) = @_;
560 return unless my $c = $self->{_cs}->{$id};
561 return $c->{handle};
562}
563
564
# spent 60.6ms (13.7+46.9) within Mojo::IOLoop::remote_info which was called 1000 times, avg 61µs/call: # 1000 times (13.7ms+46.9ms) by Mojo::Server::Daemon::_build_tx at line 135 of Mojo/Server/Daemon.pm, avg 61µs/call
sub remote_info {
565500013.9ms my ($self, $id) = @_;
566
567 # Connection
568 return {} unless my $c = $self->{_cs}->{$id};
569
570 # Socket
571 return {} unless my $socket = $c->{handle};
572
573 # UNIX domain socket info
57410001.04ms return {path => $socket->peerpath} if $socket->can('peerpath');
# spent 1.04ms making 1000 calls to UNIVERSAL::can, avg 1µs/call
575
576 # Info
577200045.9ms return {address => $socket->peerhost, port => $socket->peerport};
# spent 32.7ms making 1000 calls to IO::Socket::INET::peerhost, avg 33µs/call # spent 13.2ms making 1000 calls to IO::Socket::INET::peerport, avg 13µs/call
578}
579
580sub resolve {
581 my ($self, $name, $type, $cb) = @_;
582
583 # Regex
584 my $ipv4;
585 $ipv4 = 1 if $name =~ $Mojo::URL::IPV4_RE;
586 my $ipv6;
587 $ipv6 = 1 if PTON && $name =~ $Mojo::URL::IPV6_RE;
588
589 # Type
590 my $t = $DNS_TYPES->{$type};
591
592 # Server
593 my $server = $self->dns_server;
594
595 # No lookup required or record type not supported
596 if (!$server || !$t || ($t ne $DNS_TYPES->{PTR} && ($ipv4 || $ipv6))) {
597 $self->timer(0 => sub { $self->$cb([]) });
598 return $self;
599 }
600
601 # Debug
602 warn "RESOLVE $type $name ($server)\n" if DEBUG;
603
604 # Timer
605 my $timer;
606
607 # Transaction
608 my $tx = int rand 0x10000;
609
610 # Request
611 my $id = $self->connect(
612 address => $server,
613 port => 53,
614 proto => 'udp',
615 on_connect => sub {
616 my ($self, $id) = @_;
617
618 # Header (one question with recursion)
619 my $req = pack 'nnnnnn', $tx, 0x0100, 1, 0, 0, 0;
620
621 # Parts
622 my @parts = split /\./, $name;
623
624 # Reverse
625 if ($t eq $DNS_TYPES->{PTR}) {
626
627 # IPv4
628 if ($ipv4) { @parts = reverse 'arpa', 'in-addr', @parts }
629
630 # IPv6
631 elsif ($ipv6) {
632 @parts = reverse 'arpa', 'ip6', split //, unpack 'H32',
633 Socket::inet_pton(PTON_AF_INET6, $name);
634 }
635 }
636
637 # Query (Internet)
638 for my $part (@parts) {
639 $req .= pack 'C/a', $part if defined $part;
640 }
641 $req .= pack 'Cnn', 0, $t, 0x0001;
642
643 # Write
644 $self->write($id => $req);
645 },
646 on_error => sub {
647 my ($self, $id) = @_;
648
649 # Debug
650 warn "FAILED $type $name ($server)\n" if DEBUG;
651
652 $self->drop($timer) if $timer;
653 $self->$cb([]);
654 },
655 on_read => sub {
656 my ($self, $id, $chunk) = @_;
657
658 # Cleanup
659 $self->drop($id);
660 $self->drop($timer) if $timer;
661
662 # Packet
663 my @packet = unpack 'nnnnnna*', $chunk;
664
665 # Debug
666 warn "ANSWERS $packet[3] ($server)\n" if DEBUG;
667
668 # Wrong response
669 return $self->$cb([]) unless $packet[0] eq $tx;
670
671 # Content
672 my $content = $packet[6];
673
674 # Questions
675 for (1 .. $packet[2]) {
676 my $n;
677 do { ($n, $content) = unpack 'C/aa*', $content } while ($n ne '');
678 $content = (unpack 'nna*', $content)[2];
679 }
680
681 # Answers
682 my @answers;
683 for (1 .. $packet[3]) {
684
685 # Parse
686 (my ($t, $a), $content) = (unpack 'nnnNn/aa*', $content)[1, 4, 5];
687 my @answer = _parse_answer($t, $a, $chunk, $content);
688
689 # No answer
690 next unless @answer;
691
692 # Answer
693 push @answers, \@answer;
694
695 # Debug
696 warn "ANSWER $answer[0] $answer[1]\n" if DEBUG;
697 }
698
699 # Done
700 $self->$cb(\@answers);
701 }
702 );
703
704 # Timer
705 $timer = $self->timer(
706 $self->dns_timeout => sub {
707 my $self = shift;
708
709 # Debug
710 warn "RESOLVE TIMEOUT ($server)\n" if DEBUG;
711
712 # Abort
713 $self->drop($id);
714 $self->$cb([]);
715 }
716 );
717
718 return $self;
719}
720
72117µs144µs
# spent 52µs (8+43) within Mojo::IOLoop::singleton which was called: # once (8µs+43µs) by Mojo::Server::Daemon::__ANON__[/Users/marcus/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Mojo/Server/Daemon.pm:21] at line 21 of Mojo/Server/Daemon.pm
sub singleton { $LOOP ||= shift->new(@_) }
# spent 44µs making 1 call to Mojo::IOLoop::new
722
723
# spent 21.3s (11.2ms+21.3) within Mojo::IOLoop::start which was called: # once (11.2ms+21.3s) by Mojo::Server::Daemon::run at line 83 of Mojo/Server/Daemon.pm
sub start {
72447.67ms my $self = shift;
725
726 # Already running
727 return if $self->{_running};
728
729 # Running
730 $self->{_running} = 1;
731
732 # Mainloop
733249921.3s $self->one_tick while $self->{_running};
# spent 21.3s making 2499 calls to Mojo::IOLoop::one_tick, avg 8.53ms/call
734
735 return $self;
736}
737
738sub start_tls {
739 my $self = shift;
740 my $id = shift;
741
742 # Shortcut
743 $self->drop($id) and return unless TLS;
744
745 # Arguments
746 my $args = ref $_[0] ? $_[0] : {@_};
747
748 # Weaken
749 weaken $self;
750
751 # Options
752 my %options = (
753 SSL_startHandshake => 0,
754 SSL_error_trap => sub { $self->_error($id, $_[1]) },
755 SSL_cert_file => $args->{tls_cert},
756 SSL_key_file => $args->{tls_key},
757 Timeout => $self->connect_timeout,
758 %{$args->{tls_args} || {}}
759 );
760
761 # Connection
762 $self->drop($id) and return unless my $c = $self->{_cs}->{$id};
763
764 # Socket
765 $self->drop($id) and return unless my $socket = $c->{handle};
766 my $fd = fileno $socket;
767
768 # Cleanup
769 delete $self->{_reverse}->{$socket};
770 my $writing = delete $c->{writing};
771 my $loop = $self->_prepare_loop;
772 if (KQUEUE) {
773 $loop->EV_SET($fd, KQUEUE_READ, KQUEUE_DELETE) if defined $writing;
774 $loop->EV_SET($fd, KQUEUE_WRITE, KQUEUE_DELETE) if $writing;
775 }
776 else { $loop->remove($socket) if defined $writing }
777
778 # Start
779 $self->drop($id) and return
780 unless my $new = IO::Socket::SSL->start_SSL($socket, %options);
781
782 # Upgrade
783 $c->{handle} = $new;
784 $self->{_reverse}->{$new} = $id;
785 $c->{tls_connect} = 1;
786 $self->_writing($id);
787
788 return $id;
789}
790
791sub stop { delete shift->{_running} }
792
793sub test {
794 my ($self, $id) = @_;
795
796 # Connection
797 return unless my $c = $self->{_cs}->{$id};
798
799 # Socket
800 return unless my $socket = $c->{handle};
801
802 # Test
803 my $test = $self->{_test} ||= IO::Poll->new;
804 $test->mask($socket, POLLIN);
805 $test->poll(0);
806 my $result = $test->handles(POLLIN | POLLERR | POLLHUP);
807 $test->remove($socket);
808
809 return !$result;
810}
811
812sub timer {
813 shift->_add_loop_event(timer => pop, after => pop, started => time);
814}
815
816
# spent 89.3ms (12.6+76.7) within Mojo::IOLoop::write which was called 1000 times, avg 89µs/call: # 1000 times (12.6ms+76.7ms) by Mojo::Server::Daemon::_write at line 405 of Mojo/Server/Daemon.pm, avg 89µs/call
sub write {
817800011.6ms my ($self, $id, $chunk, $cb) = @_;
818
819 # Connection
820 my $c = $self->{_cs}->{$id};
821
822 # Buffer
823 $c->{buffer} .= $chunk;
824
825 # UNIX only
826 unless (WINDOWS) {
827
828 # Callback
829 $c->{drain} = 0 if $cb;
830
831 # Fast write
832100076.7ms $self->_write($id);
# spent 76.7ms making 1000 calls to Mojo::IOLoop::_write, avg 77µs/call
833 }
834
835 # Callback
836 $c->{drain} = $cb if $cb;
837
838 # Writing
839 $self->_writing($id) if $cb || length $c->{buffer};
840}
841
842
# spent 327ms (75.8+251) within Mojo::IOLoop::_accept which was called 1000 times, avg 327µs/call: # 1000 times (75.8ms+251ms) by Mojo::IOLoop::_read at line 1368, avg 327µs/call
sub _accept {
8433500075.9ms my ($self, $listen) = @_;
844
845 # Accept
8461000117ms my $socket = $listen->accept or return;
# spent 117ms making 1000 calls to IO::Socket::accept, avg 117µs/call
847
848 # Unlock
84920007.85ms $self->on_unlock->($self);
# spent 5.60ms making 1000 calls to Mojo::Base::__ANON__[(eval 61)[Mojo/Base.pm:123]:8], avg 6µs/call # spent 2.25ms making 1000 calls to Mojo::IOLoop::__ANON__[Mojo/IOLoop.pm:137], avg 2µs/call
850
851 # Reverse map
852 my $r = $self->{_reverse};
853
854 # Listen
855 my $l = $self->{_listen}->{$r->{$listen}};
856
857 # Weaken
85810001.48ms weaken $self;
# spent 1.48ms making 1000 calls to Scalar::Util::weaken, avg 1µs/call
859
860 # Connection
861 my $c = {buffer => ''};
86210005.00ms (my $id) = "$c" =~ /0x([\da-f]+)/;
# spent 5.00ms making 1000 calls to Mojo::IOLoop::CORE:match, avg 5µs/call
863 $self->{_cs}->{$id} = $c;
864
865 # TLS handshake
866 if (my $tls = $l->{tls}) {
867 $tls->{SSL_error_trap} = sub { $self->_error($id, $_[1]) };
868 $socket = IO::Socket::SSL->start_SSL($socket, %$tls);
869 $c->{tls_accept} = 1;
870 }
871
872 # Socket
873 $c->{handle} = $socket;
874 $r->{$socket} = $id;
875
876 # Non-blocking
877100014.8ms $socket->blocking(0);
# spent 14.8ms making 1000 calls to IO::Socket::blocking, avg 15µs/call
878
879 # Disable Nagle's algorithm
88010004.17ms setsockopt($socket, IPPROTO_TCP, TCP_NODELAY, 1) unless $l->{file};
# spent 4.17ms making 1000 calls to Mojo::IOLoop::CORE:ssockopt, avg 4µs/call
881
882 # File descriptor
883 my $fd = fileno $socket;
884 $self->{_fds}->{$fd} = $id;
885
886 # Register callbacks
887 for my $name (qw/on_error on_hup on_read/) {
888 my $cb = $l->{$name};
889300023.5ms $self->$name($id => $cb) if $cb;
# spent 10.6ms making 1000 calls to Mojo::IOLoop::on_error, avg 11µs/call # spent 6.60ms making 1000 calls to Mojo::IOLoop::on_read, avg 7µs/call # spent 6.33ms making 1000 calls to Mojo::IOLoop::on_hup, avg 6µs/call
890 }
891
892 # Add socket to poll
893100032.8ms $self->_not_writing($id);
# spent 32.8ms making 1000 calls to Mojo::IOLoop::_not_writing, avg 33µs/call
894
895 # Accept limit
896 if (defined $self->{_accepts}) {
897 $self->max_connections(0) if --$self->{_accepts} == 0;
898 }
899
900 # Debug
901 warn "ACCEPTED $id\n" if DEBUG;
902
903 # Accept callback
904 my $cb = $c->{on_accept} = $l->{on_accept};
905100031.2ms $self->_run_event('accept', $cb, $id) if $cb && !$l->{tls};
# spent 31.2ms making 1000 calls to Mojo::IOLoop::_run_event, avg 31µs/call
906
907 # Remove listen sockets
908 $listen = $self->{_listen} || {};
909 my $loop = $self->{_loop};
910 for my $lid (keys %$listen) {
911 my $socket = $listen->{$lid}->{handle};
912
913 # Remove listen socket from kqueue
9141000977µs if (KQUEUE) {
# spent 977µs making 1000 calls to constant::__ANON__[constant.pm:121], avg 977ns/call
915 $loop->EV_SET(fileno $socket, KQUEUE_READ, KQUEUE_DELETE);
916 }
917
918 # Remove listen socket from poll or epoll
919100011.8ms else { $loop->remove($socket) }
# spent 11.8ms making 1000 calls to IO::Poll::remove, avg 12µs/call
920 }
921
922 # Not listening anymore
923 delete $self->{_listening};
924}
925
926
# spent 9.83ms within Mojo::IOLoop::_add_event which was called 3000 times, avg 3µs/call: # 1000 times (5.07ms+0s) by Mojo::IOLoop::on_error at line 440, avg 5µs/call # 1000 times (2.45ms+0s) by Mojo::IOLoop::on_hup at line 441, avg 2µs/call # 1000 times (2.31ms+0s) by Mojo::IOLoop::on_read at line 443, avg 2µs/call
sub _add_event {
9271200012.0ms my ($self, $event, $id, $cb) = @_;
928
929 # Connection
930 return unless my $c = $self->{_cs}->{$id};
931
932 # Add event callback
933 $c->{$event} = $cb if $cb;
934
935 return $self;
936}
937
938sub _add_loop_event {
939 my $self = shift;
940 my $event = shift;
941 my $cb = shift;
942
943 # Event
944 my $e = {cb => $cb, @_};
945
946 # Add event
947 (my $id) = "$e" =~ /0x([\da-f]+)/;
948 $self->{"_$event"}->{$id} = $e;
949
950 return $id;
951}
952
953sub _connect {
954 my ($self, $id, $args) = @_;
955
956 # Connection
957 return unless my $c = $self->{_cs}->{$id};
958
959 # Options
960 my %options = (
961 Blocking => 0,
962 PeerAddr => $args->{address},
963 PeerPort => $args->{port} || ($args->{tls} ? 443 : 80),
964 Proto => $args->{proto},
965 Type => $args->{proto} eq 'udp' ? SOCK_DGRAM : SOCK_STREAM,
966 %{$args->{args} || {}}
967 );
968
969 # Handle
970 my $handle;
971 unless ($handle = $args->{handle} || $args->{socket}) {
972
973 # Socket
974 return $self->_error($id, "Couldn't connect.")
975 unless $handle = IO::Socket::INET->new(%options);
976
977 # Disable Nagle's algorithm
978 setsockopt $handle, IPPROTO_TCP, TCP_NODELAY, 1;
979
980 # Timer
981 $c->{connect_timer} =
982 $self->timer(
983 $self->connect_timeout => sub { shift->_error($id, 'Connect timeout.') }
984 );
985 }
986 $c->{handle} = $handle;
987 $self->{_reverse}->{$handle} = $id;
988
989 # Non-blocking
990 $handle->blocking(0);
991
992 # File descriptor
993 return unless defined(my $fd = fileno $handle);
994 $self->{_fds}->{$fd} = $id;
995
996 # Add handle to poll
997 $self->_writing($id);
998
999 # Start TLS
1000 if ($args->{tls}) { $self->start_tls($id => $args) }
1001}
1002
1003
# spent 82.2ms (36.3+45.9) within Mojo::IOLoop::_drop_immediately which was called 1001 times, avg 82µs/call: # 1000 times (36.2ms+45.8ms) by Mojo::IOLoop::_hup at line 1096, avg 82µs/call # once (99µs+72µs) by Mojo::IOLoop::drop at line 241
sub _drop_immediately {
10041802053.1ms my ($self, $id) = @_;
1005
1006 # Drop loop events
1007 for my $event (qw/idle tick timer/) {
1008 if ($self->{"_$event"}->{$id}) {
1009
1010 # Drop
1011 delete $self->{"_$event"}->{$id};
1012 return $self;
1013 }
1014 }
1015
1016 # Delete connection
1017 my $c = delete $self->{_cs}->{$id};
1018 delete $self->{_reverse}->{$id};
1019
1020 # Drop listen socket
1021 if (!$c && ($c = delete $self->{_listen}->{$id})) {
1022
1023 # Not listening
1024 return $self unless $self->{_listening};
1025
1026 # Not listening anymore
1027 delete $self->{_listening};
1028 }
1029
1030 # Delete associated timers
1031 if (my $t = $c->{connect_timer} || $c->{accept_timer}) {
1032 $self->_drop_immediately($t);
1033 }
1034
1035 # Drop handle
1036 if (my $handle = $c->{handle}) {
1037
1038 # Debug
1039 warn "DISCONNECTED $id\n" if DEBUG;
1040
1041 # Remove file descriptor
1042 return unless my $fd = fileno $handle;
1043 delete $self->{_fds}->{$fd};
1044
1045 # Remove handle from kqueue
104610011.65ms if (my $loop = $self->_prepare_loop) {
# spent 1.65ms making 1001 calls to Mojo::IOLoop::_prepare_loop, avg 2µs/call
104710013.13ms if (KQUEUE) {
# spent 3.13ms making 1001 calls to constant::__ANON__[constant.pm:121], avg 3µs/call
1048
1049 # Writing
1050 my $writing = $c->{writing};
1051 $loop->EV_SET($fd, KQUEUE_READ, KQUEUE_DELETE)
1052 if defined $writing;
1053 $loop->EV_SET($fd, KQUEUE_WRITE, KQUEUE_DELETE) if $writing;
1054 }
1055
1056 # Remove handle from poll or epoll
1057100120.9ms else { $loop->remove($handle) }
# spent 20.9ms making 1001 calls to IO::Poll::remove, avg 21µs/call
1058 }
1059
1060 # Close handle
1061100120.2ms close $handle;
# spent 20.2ms making 1001 calls to Mojo::IOLoop::CORE:close, avg 20µs/call
1062 }
1063
1064 return $self;
1065}
1066
1067sub _error {
1068 my ($self, $id, $error) = @_;
1069
1070 # Connection
1071 return unless my $c = $self->{_cs}->{$id};
1072
1073 # Get error callback
1074 my $event = $c->{error};
1075
1076 # Cleanup
1077 $self->_drop_immediately($id);
1078
1079 # Error
1080 $error ||= 'Unknown error, probably harmless.';
1081
1082 # No event
1083 warn "Unhandled event error: $error" and return unless $event;
1084
1085 # Error callback
1086 $self->_run_event('error', $event, $id, $error);
1087}
1088
1089
# spent 121ms (13.1+108) within Mojo::IOLoop::_hup which was called 1000 times, avg 121µs/call: # 1000 times (13.1ms+108ms) by Mojo::IOLoop::_prepare_connections at line 1250, avg 121µs/call
sub _hup {
1090500010.7ms my ($self, $id) = @_;
1091
1092 # Get hup callback
1093 my $event = $self->{_cs}->{$id}->{hup};
1094
1095 # Cleanup
1096100082.0ms $self->_drop_immediately($id);
# spent 82.0ms making 1000 calls to Mojo::IOLoop::_drop_immediately, avg 82µs/call
1097
1098 # No event
1099 return unless $event;
1100
1101 # HUP callback
1102100026.3ms $self->_run_event('hup', $event, $id);
# spent 26.3ms making 1000 calls to Mojo::IOLoop::_run_event, avg 26µs/call
1103}
1104
1105
# spent 41.7ms (27.7+14.0) within Mojo::IOLoop::_not_writing which was called 2000 times, avg 21µs/call: # 1000 times (18.7ms+14.0ms) by Mojo::IOLoop::_accept at line 893, avg 33µs/call # 1000 times (8.97ms+0s) by Mojo::IOLoop::_write at line 1586, avg 9µs/call
sub _not_writing {
11061800022.4ms my ($self, $id) = @_;
1107
1108 # Connection
1109 return unless my $c = $self->{_cs}->{$id};
1110
1111 # Chunk still in buffer
1112 return $c->{read_only} = 1 if length $c->{buffer};
1113
1114 # Handle
1115 return unless my $handle = $c->{handle};
1116
1117 # Writing
1118 my $writing = $c->{writing};
1119 return if defined $writing && !$writing;
1120
1121 # KQueue
112210001.81ms my $loop = $self->_prepare_loop;
# spent 1.81ms making 1000 calls to Mojo::IOLoop::_prepare_loop, avg 2µs/call
112310001.41ms if (KQUEUE) {
# spent 1.41ms making 1000 calls to constant::__ANON__[constant.pm:121], avg 1µs/call
1124 my $fd = fileno $handle;
1125
1126 # Writing
1127 $loop->EV_SET($fd, KQUEUE_READ, KQUEUE_ADD) unless defined $writing;
1128 $loop->EV_SET($fd, KQUEUE_WRITE, KQUEUE_DELETE) if $writing;
1129 }
1130
1131 # Poll and epoll
1132 else {
1133
1134 # Not writing anymore
1135 if ($writing) {
1136 $loop->remove($handle);
1137 $writing = undef;
1138 }
1139
1140 # Reading
11411000937µs my $mask = EPOLL ? EPOLL_POLLIN : POLLIN;
# spent 937µs making 1000 calls to constant::__ANON__[constant.pm:121], avg 937ns/call
114210009.89ms $loop->mask($handle, $mask) unless defined $writing;
# spent 9.89ms making 1000 calls to IO::Poll::mask, avg 10µs/call
1143 }
1144
1145 # Not writing anymore
1146 $c->{writing} = 0;
1147}
1148
1149# Answer helper for "resolve"
1150sub _parse_answer {
1151 my ($t, $a, $packet, $rest) = @_;
1152
1153 # A
1154 if ($t eq $DNS_TYPES->{A}) { return A => join('.', unpack 'C4', $a) }
1155
1156 # AAAA
1157 elsif ($t eq $DNS_TYPES->{AAAA}) {
1158 return AAAA => sprintf('%x:%x:%x:%x:%x:%x:%x:%x', unpack('n*', $a));
1159 }
1160
1161 # TXT
1162 elsif ($t eq $DNS_TYPES->{TXT}) { return TXT => unpack('(C/a*)*', $a) }
1163
1164 # Offset
1165 my $offset = length($packet) - length($rest) - length($a);
1166
1167 # CNAME
1168 my $type;
1169 if ($t eq $DNS_TYPES->{CNAME}) { $type = 'CNAME' }
1170
1171 # MX
1172 elsif ($t eq $DNS_TYPES->{MX}) {
1173 $type = 'MX';
1174 $offset += 2;
1175 }
1176
1177 # NS
1178 elsif ($t eq $DNS_TYPES->{NS}) { $type = 'NS' }
1179
1180 # PTR
1181 elsif ($t eq $DNS_TYPES->{PTR}) { $type = 'PTR' }
1182
1183 # Domain name
1184 return $type => _parse_name($packet, $offset) if $type;
1185
1186 # Not supported
1187 return;
1188}
1189
1190# Domain name helper for "resolve"
1191sub _parse_name {
1192 my ($packet, $offset) = @_;
1193
1194 # Elements
1195 my @elements;
1196 for (1 .. 128) {
1197
1198 # Element length
1199 my $len = ord substr $packet, $offset++, 1;
1200
1201 # Offset
1202 if ($len >= 0xc0) {
1203 $offset = (unpack 'n', substr $packet, ++$offset - 2, 2) & 0x3fff;
1204 }
1205
1206 # Element
1207 elsif ($len) {
1208 push @elements, substr $packet, $offset, $len;
1209 $offset += $len;
1210 }
1211
1212 # Zero length element (the end)
1213 else { return join '.', @elements }
1214 }
1215
1216 return;
1217}
1218
1219sub _prepare_cert {
1220 my $self = shift;
1221
1222 # Shortcut
1223 my $cert = $self->{_cert};
1224 return $cert if $cert && -r $cert;
1225
1226 # Create temporary TLS cert file
1227 $cert = File::Spec->catfile($ENV{MOJO_TMPDIR} || File::Spec->tmpdir,
1228 'mojocert.pem');
1229 my $file = IO::File->new;
1230 $file->open("> $cert")
1231 or croak qq/Can't create temporary TLS cert file "$cert"/;
1232 print $file CERT;
1233
1234 return $self->{_cert} = $cert;
1235}
1236
1237
# spent 182ms (48.0+134) within Mojo::IOLoop::_prepare_connections which was called 2499 times, avg 73µs/call: # 2499 times (48.0ms+134ms) by Mojo::IOLoop::one_tick at line 456, avg 73µs/call
sub _prepare_connections {
12381699645.7ms my $self = shift;
1239
1240 # Connections
1241 my $cs = $self->{_cs} ||= {};
1242
1243 # Prepare
1244 while (my ($id, $c) = each %$cs) {
1245
1246 # Connection needs to be finished
1247 if ($c->{finish} && !length $c->{buffer}) {
1248
1249 # Buffer empty
12501000121ms $self->_hup($id);
# spent 121ms making 1000 calls to Mojo::IOLoop::_hup, avg 121µs/call
1251 next;
1252 }
1253
1254 # Read only
1255 $self->_not_writing($id) if delete $c->{read_only};
1256
1257 # Last active
125810001.52ms my $time = $c->{active} ||= time;
# spent 1.52ms making 1000 calls to Time::HiRes::time, avg 2µs/call
1259
1260 # HUP
12611000767µs $self->_hup($id) if (time - $time) >= ($c->{timeout} || 15);
# spent 767µs making 1000 calls to Time::HiRes::time, avg 767ns/call
1262 }
1263
1264 # Graceful shutdown
1265249910.4ms $self->stop if $self->max_connections == 0 && keys %$cs == 0;
# spent 10.4ms making 2499 calls to Mojo::Base::__ANON__[(eval 172)[Mojo/Base.pm:123]:8], avg 4µs/call
1266}
1267
1268sub _prepare_key {
1269 my $self = shift;
1270
1271 # Shortcut
1272 my $key = $self->{_key};
1273 return $key if $key && -r $key;
1274
1275 # Create temporary TLS key file
1276 $key = File::Spec->catfile($ENV{MOJO_TMPDIR} || File::Spec->tmpdir,
1277 'mojokey.pem');
1278 my $file = IO::File->new;
1279 $file->open("> $key")
1280 or croak qq/Can't create temporary TLS key file "$key"/;
1281 print $file KEY;
1282
1283 return $self->{_key} = $key;
1284}
1285
1286
# spent 69.4ms (42.8+26.6) within Mojo::IOLoop::_prepare_listen which was called 2499 times, avg 28µs/call: # 2499 times (42.8ms+26.6ms) by Mojo::IOLoop::one_tick at line 453, avg 28µs/call
sub _prepare_listen {
12871750732.8ms my $self = shift;
1288
1289 # Loop
129024997.38ms my $loop = $self->_prepare_loop;
# spent 7.38ms making 2499 calls to Mojo::IOLoop::_prepare_loop, avg 3µs/call
1291
1292 # Already listening
1293 return if $self->{_listening};
1294
1295 # Listen sockets
1296 my $listen = $self->{_listen} ||= {};
1297 return unless keys %$listen;
1298
1299 # Connections
1300 my $i = keys %{$self->{_cs}};
130110012.27ms return unless $i < $self->max_connections;
# spent 2.27ms making 1001 calls to Mojo::Base::__ANON__[(eval 172)[Mojo/Base.pm:123]:8], avg 2µs/call
1302
1303 # Lock
130420025.81ms return unless $self->on_lock->($self, !$i);
# spent 4.28ms making 1001 calls to Mojo::Base::__ANON__[(eval 60)[Mojo/Base.pm:123]:8], avg 4µs/call # spent 1.53ms making 1001 calls to Mojo::IOLoop::__ANON__[Mojo/IOLoop.pm:137], avg 2µs/call
1305
1306 # Add listen sockets
1307 for my $lid (keys %$listen) {
1308 my $socket = $listen->{$lid}->{handle};
1309
1310 # KQueue
131120021.89ms if (KQUEUE) { $loop->EV_SET(fileno $socket, KQUEUE_READ, KQUEUE_ADD) }
# spent 1.89ms making 2002 calls to constant::__ANON__[constant.pm:121], avg 943ns/call
1312
1313 # Epoll
1314 elsif (EPOLL) { $loop->mask($socket, EPOLL_POLLIN) }
1315
1316 # Poll
131710019.21ms else { $loop->mask($socket, POLLIN) }
# spent 9.21ms making 1001 calls to IO::Poll::mask, avg 9µs/call
1318 }
1319
1320 # Listening
1321 $self->{_listening} = 1;
1322}
1323
1324
# spent 16.6ms (16.3+261µs) within Mojo::IOLoop::_prepare_loop which was called 6999 times, avg 2µs/call: # 2499 times (7.12ms+261µs) by Mojo::IOLoop::_prepare_listen at line 1290, avg 3µs/call # 2499 times (5.72ms+0s) by Mojo::IOLoop::one_tick at line 459, avg 2µs/call # 1001 times (1.65ms+0s) by Mojo::IOLoop::_drop_immediately at line 1046, avg 2µs/call # 1000 times (1.81ms+0s) by Mojo::IOLoop::_not_writing at line 1122, avg 2µs/call
sub _prepare_loop {
13251400324.2ms my $self = shift;
1326
1327 # Already initialized
1328 return $self->{_loop} if $self->{_loop};
1329
1330 # "kqueue"
1331216µs if (KQUEUE) {
# spent 16µs making 2 calls to constant::__ANON__[constant.pm:121], avg 8µs/call
1332
1333 # Debug
1334 warn "KQUEUE MAINLOOP\n" if DEBUG;
1335
1336 return $self->{_loop} = IO::KQueue->new;
1337 }
1338
1339 # "epoll"
1340 elsif (EPOLL) {
1341
1342 # Debug
1343 warn "EPOLL MAINLOOP\n" if DEBUG;
1344
1345 $self->{_loop} = IO::Epoll->new;
1346 }
1347
1348 # "poll"
1349 else {
1350
1351 # Debug
1352 warn "POLL MAINLOOP\n" if DEBUG;
1353
1354118µs $self->{_loop} = IO::Poll->new;
# spent 18µs making 1 call to IO::Poll::new
1355 }
1356
1357 # Dummy handle to make empty poll respect the timeout and block
13583228µs $self->{_loop}
# spent 212µs making 1 call to IO::Socket::INET::new # spent 14µs making 1 call to IO::Poll::mask # spent 1µs making 1 call to constant::__ANON__[constant.pm:121]
1359 ->mask(IO::Socket::INET->new(Listen => 1), EPOLL ? EPOLL_POLLIN : POLLIN);
1360
1361 return $self->{_loop};
1362}
1363
1364
# spent 8.04s (26.6ms+8.02) within Mojo::IOLoop::_read which was called 2000 times, avg 4.02ms/call: # 2000 times (26.6ms+8.02s) by Mojo::IOLoop::one_tick at line 532, avg 4.02ms/call
sub _read {
13651800026.8ms my ($self, $id) = @_;
1366
1367 # Listen socket (new connection)
13681000327ms if (my $l = $self->{_listen}->{$id}) { $self->_accept($l->{handle}) }
# spent 327ms making 1000 calls to Mojo::IOLoop::_accept, avg 327µs/call
1369
1370 # Connection
1371 my $c = $self->{_cs}->{$id};
1372
1373 # TLS accept
1374 return $self->_tls_accept($id) if $c->{tls_accept};
1375
1376 # TLS connect
1377 return $self->_tls_connect($id) if $c->{tls_connect};
1378
1379 # Handle
1380 return unless defined(my $handle = $c->{handle});
1381
1382 # Read as much as possible
1383100013.8ms my $read = $handle->sysread(my $buffer, 4194304, 0);
# spent 13.8ms making 1000 calls to IO::Handle::sysread, avg 14µs/call
1384
1385 # Error
1386 unless (defined $read) {
1387
1388 # Retry
1389 return if $! == EAGAIN || $! == EWOULDBLOCK;
1390
1391 # Connection reset
1392 return $self->_hup($id) if $! == ECONNRESET;
1393
1394 # Read error
1395 return $self->_error($id, $!);
1396 }
1397
1398 # EOF
1399 return $self->_hup($id) if $read == 0;
1400
1401 # Callback
1402 my $event = $c->{read};
140310007.67s $self->_run_event('read', $event, $id, $buffer) if $event;
# spent 7.67s making 1000 calls to Mojo::IOLoop::_run_event, avg 7.67ms/call
1404
1405 # Active
140610001.23ms $c->{active} = time;
# spent 1.23ms making 1000 calls to Time::HiRes::time, avg 1µs/call
1407}
1408
1409# Failed callbacks should not kill everything
1410sub _run_callback {
1411 my $self = shift;
1412 my $event = shift;
1413 my $cb = shift;
1414
1415 # Invoke callback
1416 my $value = eval { $self->$cb(@_) };
1417
1418 # Callback error
1419 warn qq/Callback "$event" failed: $@/ if $@;
1420
1421 return $value;
1422}
1423
1424# Failed events should not kill everything
1425
# spent 7.73s (24.2ms+7.71) within Mojo::IOLoop::_run_event which was called 3000 times, avg 2.58ms/call: # 1000 times (8.52ms+7.67s) by Mojo::IOLoop::_read at line 1403, avg 7.67ms/call # 1000 times (6.18ms+25.0ms) by Mojo::IOLoop::_accept at line 905, avg 31µs/call # 1000 times (9.48ms+16.9ms) by Mojo::IOLoop::_hup at line 1102, avg 26µs/call
sub _run_event {
14262400021.6ms my $self = shift;
1427 my $event = shift;
1428 my $cb = shift;
1429 my $id = shift;
1430
1431 # Invoke callback
143230007.71s my $value = eval { $self->$cb($id, @_) };
# spent 7.67s making 1000 calls to Mojo::Server::Daemon::__ANON__[Mojo/Server/Daemon.pm:296], avg 7.67ms/call # spent 25.0ms making 1000 calls to Mojo::Server::Daemon::__ANON__[Mojo/Server/Daemon.pm:293], avg 25µs/call # spent 16.9ms making 1000 calls to Mojo::Server::Daemon::__ANON__[Mojo/Server/Daemon.pm:295], avg 17µs/call
1433
1434 # Event error
1435 if ($@) {
1436 my $message = qq/Event "$event" failed for connection "$id": $@/;
1437 $event eq 'error'
1438 ? ($self->_drop_immediately($id) and warn $message)
1439 : $self->_error($id, $message);
1440 }
1441
1442 return $value;
1443}
1444
1445
# spent 14.4ms within Mojo::IOLoop::_timer which was called 2498 times, avg 6µs/call: # 2498 times (14.4ms+0s) by Mojo::IOLoop::one_tick at line 544, avg 6µs/call
sub _timer {
14461208515.3ms my $self = shift;
1447
1448 # Timers
1449 return unless my $ts = $self->{_timer};
1450
1451 # Check
1452 my $count = 0;
1453 for my $id (keys %$ts) {
1454 my $t = $ts->{$id};
1455
1456 # Timer
1457 my $after = $t->{after} || 0;
1458 if ($after <= time - $t->{started}) {
1459
1460 # Drop
1461 $self->_drop_immediately($id);
1462
1463 # Callback
1464 if (my $cb = $t->{cb}) {
1465 $self->_run_callback('timer', $cb);
1466 $count++;
1467 }
1468 }
1469 }
1470
1471 return $count;
1472}
1473
1474sub _tls_accept {
1475 my ($self, $id) = @_;
1476
1477 # Connection
1478 my $c = $self->{_cs}->{$id};
1479
1480 # Accepted
1481 if ($c->{handle}->accept_SSL) {
1482
1483 # Cleanup
1484 delete $c->{tls_accept};
1485
1486 # Accept callback
1487 my $cb = $c->{on_accept};
1488 $self->_run_event('accept', $cb, $id) if $cb;
1489
1490 return;
1491 }
1492
1493 # Handle error
1494 $self->_tls_error($id);
1495}
1496
1497sub _tls_connect {
1498 my ($self, $id) = @_;
1499
1500 # Connection
1501 my $c = $self->{_cs}->{$id};
1502
1503 # Connected
1504 if ($c->{handle}->connect_SSL) {
1505
1506 # Cleanup
1507 delete $c->{tls_connect};
1508
1509 # Connect callback
1510 my $cb = $c->{on_connect};
1511 $self->_run_event('connect', $cb, $id) if $cb;
1512
1513 return;
1514 }
1515
1516 # Handle error
1517 $self->_tls_error($id);
1518}
1519
1520sub _tls_error {
1521 my ($self, $id) = @_;
1522
1523 # Error
1524 my $error = $IO::Socket::SSL::SSL_ERROR;
1525
1526 # Reading
1527 if ($error == TLS_READ) { $self->_not_writing($id) }
1528
1529 # Writing
1530 elsif ($error == TLS_WRITE) { $self->_writing($id) }
1531}
1532
1533
# spent 76.7ms (26.2+50.5) within Mojo::IOLoop::_write which was called 1000 times, avg 77µs/call: # 1000 times (26.2ms+50.5ms) by Mojo::IOLoop::write at line 832, avg 77µs/call
sub _write {
15341200026.2ms my ($self, $id) = @_;
1535
1536 # Connection
1537 my $c = $self->{_cs}->{$id};
1538
1539 # TLS accept
1540 return $self->_tls_accept($id) if $c->{tls_accept};
1541
1542 # TLS connect
1543 return $self->_tls_connect($id) if $c->{tls_connect};
1544
1545 # Handle
1546 return unless my $handle = $c->{handle};
1547
1548 # Connecting
1549 if ($c->{connecting}) {
1550
1551 # Cleanup
1552 delete $c->{connecting};
1553 my $timer = delete $c->{connect_timer};
1554 $self->_drop_immediately($timer) if $timer;
1555
1556 # Debug
1557 warn "CONNECTED $id\n" if DEBUG;
1558
1559 # Connect callback
1560 my $cb = $c->{on_connect};
1561 $self->_run_event('connect', $cb, $id) if $cb && !$c->{tls};
1562 }
1563
1564 # Callback
1565 if ($c->{drain} && (my $event = delete $c->{drain})) {
1566 $self->_run_event('drain', $event, $id);
1567 }
1568
1569 # Write
1570100039.0ms my $written = $handle->syswrite($c->{buffer});
# spent 39.0ms making 1000 calls to IO::Handle::syswrite, avg 39µs/call
1571
1572 # Error
1573 unless (defined $written) {
1574
1575 # Retry
1576 return if $! == EAGAIN || $! == EWOULDBLOCK;
1577
1578 # Write error
1579 return $self->_error($id, $!);
1580 }
1581
1582 # Remove written chunk from buffer
1583 substr $c->{buffer}, 0, $written, '';
1584
1585 # Not writing
158610008.97ms $self->_not_writing($id) unless exists $c->{drain} || length $c->{buffer};
# spent 8.97ms making 1000 calls to Mojo::IOLoop::_not_writing, avg 9µs/call
1587
1588 # Active
158910002.49ms $c->{active} = time if $written;
# spent 2.49ms making 1000 calls to Time::HiRes::time, avg 2µs/call
1590}
1591
1592sub _writing {
1593 my ($self, $id) = @_;
1594
1595 # Connection
1596 my $c = $self->{_cs}->{$id};
1597
1598 # Writing again
1599 delete $c->{read_only};
1600
1601 # Writing
1602 return if my $writing = $c->{writing};
1603
1604 # Handle
1605 return unless my $handle = $c->{handle};
1606
1607 # KQueue
1608 my $loop = $self->_prepare_loop;
1609 if (KQUEUE) {
1610 my $fd = fileno $handle;
1611
1612 # Writing
1613 $loop->EV_SET($fd, KQUEUE_READ, KQUEUE_ADD) unless defined $writing;
1614 $loop->EV_SET($fd, KQUEUE_WRITE, KQUEUE_ADD) unless $writing;
1615 }
1616
1617 # Poll and epoll
1618 else {
1619
1620 # Cleanup
1621 $loop->remove($handle);
1622
1623 # Writing
1624 my $mask = EPOLL ? EPOLL_POLLIN | EPOLL_POLLOUT : POLLIN | POLLOUT;
1625 $loop->mask($handle, $mask);
1626 }
1627
1628 # Writing
1629 $c->{writing} = 1;
1630}
1631
1632124µs1;
1633__END__
 
# spent 20.2ms within Mojo::IOLoop::CORE:close which was called 1001 times, avg 20µs/call: # 1001 times (20.2ms+0s) by Mojo::IOLoop::_drop_immediately at line 1061, avg 20µs/call
sub Mojo::IOLoop::CORE:close; # opcode
# spent 29µs within Mojo::IOLoop::CORE:fteread which was called: # once (29µs+0s) by Mojo::Client::BEGIN@10 at line 102
sub Mojo::IOLoop::CORE:fteread; # opcode
# spent 5.01ms within Mojo::IOLoop::CORE:match which was called 1015 times, avg 5µs/call: # 1000 times (5.00ms+0s) by Mojo::IOLoop::_accept at line 862, avg 5µs/call # 12 times (6µs+0s) by Mojo::Client::BEGIN@10 at line 106, avg 525ns/call # once (3µs+0s) by Mojo::IOLoop::listen at line 307 # once (900ns+0s) by Mojo::IOLoop::BEGIN@50 at line 50 # once (200ns+0s) by Mojo::IOLoop::listen at line 297
sub Mojo::IOLoop::CORE:match; # opcode
# spent 14µs within Mojo::IOLoop::CORE:readline which was called: # once (14µs+0s) by Mojo::Client::BEGIN@10 at line 105
sub Mojo::IOLoop::CORE:readline; # opcode
# spent 26µs within Mojo::IOLoop::CORE:regcomp which was called: # once (26µs+0s) by Mojo::IOLoop::listen at line 297
sub Mojo::IOLoop::CORE:regcomp; # opcode
# spent 4.17ms within Mojo::IOLoop::CORE:ssockopt which was called 1000 times, avg 4µs/call: # 1000 times (4.17ms+0s) by Mojo::IOLoop::_accept at line 880, avg 4µs/call
sub Mojo::IOLoop::CORE:ssockopt; # opcode