server.txt


sub listen {
    my $self   = shift;
    my $server = $self->create_localsocket;
    my $select = IO::Select->new($server);
    my(%buf, %timestamp);

    LISTEN:
    while(1) {

        CHECK_TIMEOUT:
        for($select->handles) {
            next CHECK_TIMEOUT if($_ == $server);
            if($timestamp{$_} < time - $self->Timeout) {
                delete $buf{$_};
                $select->remove($_);
                $_->close;
            }
        }

        CONNECTION:
        for my $conn (@_ = $select->can_read(1)) {

            ### client
            if($conn != $server) {

                ### get input
                my $input;
                my $recv     = $conn->sysread($input, 1024, 0);
                $buf{$conn} .= $input;

                ### EOT
                unless(defined $recv and length $input) {
                    $timestamp{$conn} = -1;
                    next CONNECTION;
                }

                ### communicate
                if($self->communicate(\$buf{$conn})) {
                    $timestamp{$conn} = time;
                }
                else {
                    $timestamp{$conn} = -1;
                    next CONNECTION;
                }
            }

            ### server
            else {

                ### get new client
                $conn             = $server->accept;
                $timestamp{$conn} = time;
                $select->add($conn);
            }
        }

        ### fix timestamp
        %timestamp = map { $_ => $timestamp{$_} } $select->handles;
    }

    $server->shutdown(2);
    exit 0;
}