]> Sergey Matveev's repositories - public-inbox.git/blob - lib/PublicInbox/Listener.pm
7f9658b89b231f73b2a07a8744954bf4537a1c8c
[public-inbox.git] / lib / PublicInbox / Listener.pm
1 # Copyright (C) 2015 all contributors <meta@public-inbox.org>
2 # License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
3 package PublicInbox::Listener;
4 use strict;
5 use warnings;
6 use base 'Danga::Socket';
7 use Socket qw(SOL_SOCKET SO_KEEPALIVE IPPROTO_TCP TCP_NODELAY);
8 use fields qw(post_accept);
9 require IO::Handle;
10
11 sub new ($$$) {
12         my ($class, $s, $cb) = @_;
13         setsockopt($s, SOL_SOCKET, SO_KEEPALIVE, 1);
14         setsockopt($s, IPPROTO_TCP, TCP_NODELAY, 1);
15         listen($s, 1024);
16         IO::Handle::blocking($s, 0);
17         my $self = fields::new($class);
18         $self->SUPER::new($s); # calls epoll_create for the first socket
19         $self->watch_read(1);
20         $self->{post_accept} = $cb;
21         $self
22 }
23
24 sub event_read {
25         my ($self) = @_;
26         # no loop here, we want to fairly distribute clients
27         # between multiple processes sharing the same socket
28         if (accept(my $c, $self->{sock})) {
29                 IO::Handle::blocking($c, 0); # no accept4 :<
30                 $self->{post_accept}->($c);
31         }
32 }
33
34 1;