root/trunk/lib/Perlbal/TCPListener.pm @ 687

Revision 687, 3.8 kB (checked in by jacques, 2 years ago)

Bump copyright and fixed typo in Interactive

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1######################################################################
2# TCP listener on a given port
3#
4# Copyright 2004, Danga Interactive, Inc.
5# Copyright 2005-2007, Six Apart, Ltd.
6
7
8package Perlbal::TCPListener;
9use strict;
10use warnings;
11no  warnings qw(deprecated);
12
13use base "Perlbal::Socket";
14use fields qw(service hostport);
15use Socket qw(IPPROTO_TCP SOL_SOCKET SO_SNDBUF);
16
17# TCPListener
18sub new {
19    my ($class, $hostport, $service, $opts) = @_;
20    $opts ||= {};
21
22    my $sockclass = $opts->{ssl} ? "IO::Socket::SSL" : "IO::Socket::INET";
23    my $sock = eval {
24        $sockclass->new(
25                        LocalAddr => $hostport,
26                        Proto => IPPROTO_TCP,
27                        Listen => 1024,
28                        ReuseAddr => 1,
29                        ($opts->{ssl} ? %{$opts->{ssl}} : ()),
30                        );
31    };
32
33    return Perlbal::error("Error creating listening socket: " . ($@ || $!))
34        unless $sock;
35
36    if ($^O eq 'MSWin32') {
37        # On Windows, we have to do this a bit differently.
38        # IO::Socket should really do this for us, but whatever.
39        my $do = 1;
40        ioctl($sock, 0x8004667E, \$do) or return Perlbal::error("Unable to make listener on $hostport non-blocking: $!");
41    }
42    else {
43        # IO::Socket::INET's Blocking => 0 just doesn't seem to work
44        # on lots of perls.  who knows why.
45        IO::Handle::blocking($sock, 0) or return Perlbal::error("Unable to make listener on $hostport non-blocking: $!");
46    }
47
48    my $self = $class->SUPER::new($sock);
49    $self->{service} = $service;
50    $self->{hostport} = $hostport;
51    bless $self, ref $class || $class;
52    $self->watch_read(1);
53    return $self;
54}
55
56# TCPListener: accepts a new client connection
57sub event_read {
58    my Perlbal::TCPListener $self = shift;
59
60    # accept as many connections as we can
61    while (my ($psock, $peeraddr) = $self->{sock}->accept) {
62        my $service_role = $self->{service}->role;
63
64        if (Perlbal::DEBUG >= 1) {
65            my ($pport, $pipr) = Socket::sockaddr_in($peeraddr);
66            my $pip = Socket::inet_ntoa($pipr);
67            print "Got new conn: $psock ($pip:$pport) for $service_role\n";
68        }
69
70        IO::Handle::blocking($psock, 0);
71
72        if (my $sndbuf = $self->{service}->{client_sndbuf_size}) {
73            my $rv = setsockopt($psock, SOL_SOCKET, SO_SNDBUF, pack("L", $sndbuf));
74        }
75
76        if ($service_role eq "reverse_proxy") {
77            Perlbal::ClientProxy->new($self->{service}, $psock);
78        } elsif ($service_role eq "management") {
79            Perlbal::ClientManage->new($self->{service}, $psock);
80        } elsif ($service_role eq "web_server") {
81            Perlbal::ClientHTTP->new($self->{service}, $psock);
82        } elsif ($service_role eq "selector") {
83            # will be cast to a more specific class later...
84            Perlbal::ClientHTTPBase->new($self->{service}, $psock, $self->{service});
85        } elsif (my $creator = Perlbal::Service::get_role_creator($service_role)) {
86            # was defined by a plugin, so we want to return one of these
87            $creator->($self->{service}, $psock);
88        }
89
90    }
91}
92
93sub as_string {
94    my Perlbal::TCPListener $self = shift;
95    my $ret = $self->SUPER::as_string;
96    my Perlbal::Service $svc = $self->{service};
97    $ret .= ": listening on $self->{hostport} for service '$svc->{name}'";
98    return $ret;
99}
100
101sub as_string_html {
102    my Perlbal::TCPListener $self = shift;
103    my $ret = $self->SUPER::as_string_html;
104    my Perlbal::Service $svc = $self->{service};
105    $ret .= ": listening on $self->{hostport} for service <b>$svc->{name}</b>";
106    return $ret;
107}
108
109sub die_gracefully {
110    # die off so we stop waiting for new connections
111    my $self = shift;
112    $self->close('graceful_death');
113}
114
115
1161;
117
118
119# Local Variables:
120# mode: perl
121# c-basic-indent: 4
122# indent-tabs-mode: nil
123# End:
Note: See TracBrowser for help on using the browser.