ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Coro/myhttpd/httpd.pl
(Generate patch)

Comparing cvsroot/Coro/myhttpd/httpd.pl (file contents):
Revision 1.36 by root, Sun Sep 2 00:54:00 2001 UTC vs.
Revision 1.42 by root, Wed Sep 12 16:45:59 2001 UTC

42my @pool; 42my @pool;
43 43
44# one "execution thread" 44# one "execution thread"
45sub handler { 45sub handler {
46 while () { 46 while () {
47 my $new = pop @newcons;
48 if ($new) { 47 if (@newcons) {
49 eval { 48 eval {
50 conn->new(@$new)->handle; 49 conn->new(@{pop @newcons})->handle;
51 }; 50 };
52 slog 1, "$@" if $@ && !ref $@; 51 slog 1, "$@" if $@ && !ref $@;
53 $connections->up; 52 $connections->up;
54 } else { 53 } else {
55 last if @pool >= $MAX_POOL; 54 last if @pool >= $MAX_POOL;
57 schedule; 56 schedule;
58 } 57 }
59 } 58 }
60} 59}
61 60
61sub listen_on {
62 my $listen = $_[0];
63
64 push @listen_sockets, $listen;
65
66 # the "main thread"
67 async {
68 slog 1, "accepting connections";
69 while () {
70 $connections->down;
71 push @newcons, [$listen->accept];
72 #slog 3, "accepted @$connections ".scalar(@pool);
73 if (@pool) {
74 (pop @pool)->ready;
75 } else {
76 async \&handler;
77 }
78
79 }
80 };
81}
82
62my $http_port = new Coro::Socket 83my $http_port = new Coro::Socket
63 LocalAddr => $SERVER_HOST, 84 LocalAddr => $SERVER_HOST,
64 LocalPort => $SERVER_PORT, 85 LocalPort => $SERVER_PORT,
65 ReuseAddr => 1, 86 ReuseAddr => 1,
66 Listen => 50, 87 Listen => 50,
67 or die "unable to start server"; 88 or die "unable to start server";
68 89
69push @listen_sockets, $http_port; 90listen_on $http_port;
91
92if ($SERVER_PORT2) {
93 my $http_port = new Coro::Socket
94 LocalAddr => $SERVER_HOST,
95 LocalPort => $SERVER_PORT2,
96 ReuseAddr => 1,
97 Listen => 50,
98 or die "unable to start server";
99
100 listen_on $http_port;
101}
70 102
71our $NOW; 103our $NOW;
72our $HTTP_NOW; 104our $HTTP_NOW;
73 105
74Event->timer(interval => 1, hard => 1, cb => sub { 106Event->timer(interval => 1, hard => 1, cb => sub {
75 $NOW = time; 107 $NOW = time;
76 $HTTP_NOW = time2str $NOW; 108 $HTTP_NOW = time2str $NOW;
77})->now; 109})->now;
78 110
79# the "main thread"
80async {
81 slog 1, "accepting connections";
82 while () {
83 $connections->down;
84 push @newcons, [$http_port->accept];
85 #slog 3, "accepted @$connections ".scalar(@pool);
86 if (@pool) {
87 (pop @pool)->ready;
88 } else {
89 async \&handler;
90 }
91
92 }
93};
94
95package conn; 111package conn;
96 112
97use Socket; 113use Socket;
98use HTTP::Date; 114use HTTP::Date;
99use Convert::Scalar 'weaken'; 115use Convert::Scalar 'weaken';
100use Linux::AIO; 116use Linux::AIO;
101 117
102Linux::AIO::min_parallel $::AIO_PARALLEL; 118Linux::AIO::min_parallel $::AIO_PARALLEL;
103
104my $aio_requests = new Coro::Semaphore $::AIO_PARALLEL * 4;
105 119
106Event->io(fd => Linux::AIO::poll_fileno, 120Event->io(fd => Linux::AIO::poll_fileno,
107 poll => 'r', async => 1, 121 poll => 'r', async => 1,
108 cb => \&Linux::AIO::poll_cb); 122 cb => \&Linux::AIO::poll_cb);
109 123
127 141
128read_mimetypes; 142read_mimetypes;
129 143
130sub new { 144sub new {
131 my $class = shift; 145 my $class = shift;
146 my $fh = shift;
132 my $peername = shift; 147 my $peername = shift;
133 my $fh = shift;
134 my $self = bless { fh => $fh }, $class; 148 my $self = bless { fh => $fh }, $class;
135 my (undef, $iaddr) = unpack_sockaddr_in $peername 149 my (undef, $iaddr) = unpack_sockaddr_in $peername
136 or $self->err(500, "unable to decode peername"); 150 or $self->err(500, "unable to decode peername");
137 151
138 $self->{remote_addr} = inet_ntoa $iaddr; 152 $self->{remote_addr} = inet_ntoa $iaddr;
143 $self; 157 $self;
144} 158}
145 159
146sub DESTROY { 160sub DESTROY {
147 my $self = shift; 161 my $self = shift;
148
149 $::conns--; 162 $::conns--;
150
151 $self->eoconn; 163 $self->eoconn;
152} 164}
153 165
154# end of connection 166# end of connection
155sub eoconn { 167sub eoconn {
167 179
168sub response { 180sub response {
169 my ($self, $code, $msg, $hdr, $content) = @_; 181 my ($self, $code, $msg, $hdr, $content) = @_;
170 my $res = "HTTP/1.1 $code $msg\015\012"; 182 my $res = "HTTP/1.1 $code $msg\015\012";
171 183
172 $self->{h}{connection} ||= $hdr->{Connection}; 184 $self->{h}{connection} = "close" if $hdr->{Connection} =~ /close/;
173 185
174 $res .= "Date: $HTTP_NOW\015\012"; 186 $res .= "Date: $HTTP_NOW\015\012";
175 187
176 while (my ($h, $v) = each %$hdr) { 188 while (my ($h, $v) = each %$hdr) {
177 $res .= "$h: $v\015\012" 189 $res .= "$h: $v\015\012"
519 while ($h > 0) { 531 while ($h > 0) {
520 if (0) { 532 if (0) {
521 sysread $fh, $buf, $h > $::BUFSIZE ? $::BUFSIZE : $h 533 sysread $fh, $buf, $h > $::BUFSIZE ? $::BUFSIZE : $h
522 or last; 534 or last;
523 } else { 535 } else {
524 undef $buf;
525 $aio_requests->down;
526 aio_read($fh, $l, ($h > $::BUFSIZE ? $::BUFSIZE : $h), 536 aio_read($fh, $l, ($h > $::BUFSIZE ? $::BUFSIZE : $h),
527 $buf, 0, sub { 537 $buf, 0, sub {
528 $r = $_[0]; 538 $r = $_[0];
529 $current->ready; 539 Coro::ready($current);
530 }); 540 });
531 &Coro::schedule; 541 &Coro::schedule;
532 $aio_requests->up;
533 last unless $r; 542 last unless $r;
534 } 543 }
535 my $w = $self->{fh}->syswrite($buf) 544 my $w = syswrite $self->{fh}, $buf
536 or last; 545 or last;
537 $::written += $w; 546 $::written += $w;
538 $self->{written} += $w; 547 $self->{written} += $w;
539 $l += $r; 548 $l += $r;
540 } 549 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines