Skip to content

Commit 4e8b2e8

Browse files
author
Anton Reznikov
committed
Using prebound sockets
1 parent ab20ab3 commit 4e8b2e8

File tree

1 file changed

+45
-33
lines changed

1 file changed

+45
-33
lines changed

lib/AnyEvent/HTTP/Server.pm

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ sub new {
6464
read_size => 4096,
6565
max_header_size => MAX_READ_SIZE, #4096*8,
6666
request => 'AnyEvent::HTTP::Server::Req',
67+
sockets => {},
6768
@_,
6869
}, $pkg;
6970

@@ -126,48 +127,59 @@ sub listen:method {
126127
my $self = shift;
127128

128129
for my $listen (@{ $self->{listen} }) {
129-
my ($host,$service) = split ':',$listen,2;
130-
$service = $self->{port} unless length $service;
131-
$host = $self->{host} unless length $host;
132-
$host = $AnyEvent::PROTOCOL{ipv4} < $AnyEvent::PROTOCOL{ipv6} && AF_INET6 ? "::" : "0" unless length $host;
133-
134-
my $ipn = parse_address $host
135-
or Carp::croak "$self.listen: cannot parse '$host' as host address";
136-
137-
my $af = address_family $ipn;
138-
139-
# win32 perl is too stupid to get this right :/
140-
Carp::croak "listen/socket: address family not supported"
141-
if AnyEvent::WIN32 && $af == AF_UNIX;
142-
143-
socket my $fh, $af, SOCK_STREAM, 0 or Carp::croak "listen/socket: $!";
144-
145-
if ($af == AF_INET || $af == AF_INET6) {
146-
setsockopt $fh, SOL_SOCKET, SO_REUSEADDR, 1
147-
or Carp::croak "listen/so_reuseaddr: $!"
148-
unless AnyEvent::WIN32; # work around windows bug
130+
my $fh;
131+
unless ($self->{sockets}->{$listen}) {
132+
my ($host,$service) = split ':',$listen,2;
133+
$service = $self->{port} unless length $service;
134+
$host = $self->{host} unless length $host;
135+
$host = $AnyEvent::PROTOCOL{ipv4} < $AnyEvent::PROTOCOL{ipv6} && AF_INET6 ? "::" : "0" unless length $host;
149136

150-
unless ($service =~ /^\d*$/) {
151-
$service = (getservbyname $service, "tcp")[2]
152-
or Carp::croak "tcp_listen: $service: service unknown"
137+
my $ipn = parse_address $host
138+
or Carp::croak "$self.listen: cannot parse '$host' as host address";
139+
140+
my $af = address_family $ipn;
141+
142+
# win32 perl is too stupid to get this right :/
143+
Carp::croak "listen/socket: address family not supported"
144+
if AnyEvent::WIN32 && $af == AF_UNIX;
145+
146+
socket $fh, $af, SOCK_STREAM, 0 or Carp::croak "listen/socket: $!";
147+
148+
if ($af == AF_INET || $af == AF_INET6) {
149+
setsockopt $fh, SOL_SOCKET, SO_REUSEADDR, 1
150+
or Carp::croak "listen/so_reuseaddr: $!"
151+
unless AnyEvent::WIN32; # work around windows bug
152+
153+
unless ($service =~ /^\d*$/) {
154+
$service = (getservbyname $service, "tcp")[2]
155+
or Carp::croak "tcp_listen: $service: service unknown"
156+
}
157+
} elsif ($af == AF_UNIX) {
158+
unlink $service;
153159
}
154-
} elsif ($af == AF_UNIX) {
155-
unlink $service;
156-
}
157-
158-
bind $fh, AnyEvent::Socket::pack_sockaddr( $service, $ipn )
159-
or Carp::croak "listen/bind on ".eval{Socket::inet_ntoa($ipn)}.":$service: $!";
160-
161-
if ($host eq 'unix/') {
162-
chmod oct('0777'), $service
163-
or warn "chmod $service failed: $!";
160+
161+
bind $fh, AnyEvent::Socket::pack_sockaddr( $service, $ipn )
162+
or Carp::croak "listen/bind on ".eval{Socket::inet_ntoa($ipn)}.":$service: $!";
163+
164+
if ($host eq 'unix/') {
165+
chmod oct('0777'), $service
166+
or warn "chmod $service failed: $!";
167+
}
168+
} else {
169+
$fh = delete $self->{sockets}->{$listen};
164170
}
165171

166172
fh_nonblocking $fh, 1;
167173

168174
$self->{fh} ||= $fh; # compat
169175
$self->{fhs}{fileno $fh} = $fh;
176+
$self->{fhs_named}{$listen} = $fh;
177+
}
178+
179+
for my $socket (values $self->{sockets}) {
180+
close $socket;
170181
}
182+
$self->{sockets} = {};
171183

172184
$self->prepare();
173185

0 commit comments

Comments
 (0)