@@ -30,77 +30,76 @@ pub trait Server: Send + Clone {
30
30
fn serve_forever ( self ) {
31
31
let config = self . get_config ( ) ;
32
32
debug ! ( "About to bind to {:?}" , config. bind_address) ;
33
- match TcpListener :: bind ( config. bind_address ) . listen ( ) {
33
+ let mut acceptor = match TcpListener :: bind ( config. bind_address ) . listen ( ) {
34
34
None => {
35
35
error ! ( "bind or listen failed :-(" ) ;
36
36
return ;
37
37
} ,
38
- Some ( ref mut acceptor) => {
39
- debug ! ( "listening" ) ;
40
- let ( perf_po, perf_ch) = stream ( ) ;
41
- let perf_ch = SharedChan :: new ( perf_ch) ;
42
- do spawn {
43
- perf_dumper( perf_po) ;
44
- }
45
- loop {
46
- // OK, we're sort of shadowing an IoError here. Perhaps this should be done in a
47
- // separate task so that it can safely fail...
48
- let mut error = None ;
49
- let optstream = io_error: : cond. trap( |e| {
50
- error = Some ( e) ;
51
- } ) . inside( || {
52
- acceptor. accept( )
53
- } ) ;
38
+ Some ( acceptor) => acceptor,
39
+ } ;
40
+ debug ! ( "listening" ) ;
41
+ let ( perf_po, perf_ch) = stream ( ) ;
42
+ let perf_ch = SharedChan :: new ( perf_ch) ;
43
+ do spawn {
44
+ perf_dumper( perf_po) ;
45
+ }
46
+ loop {
47
+ // OK, we're sort of shadowing an IoError here. Perhaps this should be done in a
48
+ // separate task so that it can safely fail...
49
+ let mut error = None ;
50
+ let optstream = io_error:: cond. trap ( |e| {
51
+ error = Some ( e) ;
52
+ } ) . inside ( || {
53
+ acceptor. accept ( )
54
+ } ) ;
54
55
55
- let time_start = precise_time_ns( ) ;
56
- if optstream. is_none( ) {
57
- debug ! ( "accept failed: {:?}" , error) ;
58
- // Question: is this the correct thing to do? We should probably be more
59
- // intelligent, for there are some accept failures that are likely to be
60
- // permanent, such that continuing would be a very bad idea, such as
61
- // ENOBUFS/ENOMEM; and some where it should just be ignored, e.g.
62
- // ECONNABORTED. TODO.
63
- continue ;
56
+ let time_start = precise_time_ns ( ) ;
57
+ if optstream. is_none( ) {
58
+ debug ! ( "accept failed: {:?}" , error) ;
59
+ // Question: is this the correct thing to do? We should probably be more
60
+ // intelligent, for there are some accept failures that are likely to be
61
+ // permanent, such that continuing would be a very bad idea, such as
62
+ // ENOBUFS/ENOMEM; and some where it should just be ignored, e.g.
63
+ // ECONNABORTED. TODO.
64
+ continue;
65
+ }
66
+ let child_perf_ch = perf_ch. clone ( ) ;
67
+ let child_self = self . clone ( ) ;
68
+ do spawn {
69
+ let mut time_start = time_start;
70
+ let mut stream = BufferedStream :: new ( optstream. unwrap ( ) ) ;
71
+ debug ! ( "accepted connection, got {:?}" , stream) ;
72
+ loop { // A keep-alive loop, condition at end
73
+ let time_spawned = precise_time_ns ( ) ;
74
+ let ( request, err_status) = Request :: load ( & mut stream) ;
75
+ let time_request_made = precise_time_ns ( ) ;
76
+ let mut response = ~ResponseWriter :: new ( & mut stream, request) ;
77
+ let time_response_made = precise_time_ns ( ) ;
78
+ match err_status {
79
+ Ok ( ( ) ) => {
80
+ child_self. handle_request ( request, response) ;
81
+ // Ensure that we actually do send a response:
82
+ response. try_write_headers ( ) ;
83
+ } ,
84
+ Err ( status) => {
85
+ // Uh oh, it's a response that I as a server cannot cope with.
86
+ // No good user-agent should have caused this, so for the moment
87
+ // at least I am content to send no body in the response.
88
+ response. status = status;
89
+ response. headers . content_length = Some ( 0 ) ;
90
+ response. write_headers ( ) ;
91
+ } ,
64
92
}
65
- let child_perf_ch = perf_ch. clone( ) ;
66
- let child_self = self . clone( ) ;
67
- do spawn {
68
- let mut time_start = time_start;
69
- let mut stream = BufferedStream : : new( optstream. unwrap( ) ) ;
70
- debug ! ( "accepted connection, got {:?}" , stream) ;
71
- loop { // A keep-alive loop, condition at end
72
- let time_spawned = precise_time_ns( ) ;
73
- let ( request, err_status) = Request :: load( & mut stream) ;
74
- let time_request_made = precise_time_ns( ) ;
75
- let mut response = ~ResponseWriter :: new( & mut stream, request) ;
76
- let time_response_made = precise_time_ns( ) ;
77
- match err_status {
78
- Ok ( ( ) ) => {
79
- child_self. handle_request( request, response) ;
80
- // Ensure that we actually do send a response:
81
- response. try_write_headers( ) ;
82
- } ,
83
- Err ( status) => {
84
- // Uh oh, it's a response that I as a server cannot cope with.
85
- // No good user-agent should have caused this, so for the moment
86
- // at least I am content to send no body in the response.
87
- response. status = status;
88
- response. headers. content_length = Some ( 0 ) ;
89
- response. write_headers( ) ;
90
- } ,
91
- }
92
- // Ensure the request is flushed, any Transfer-Encoding completed, etc.
93
- response. finish_response( ) ;
94
- let time_finished = precise_time_ns( ) ;
95
- child_perf_ch. send( ( time_start, time_spawned, time_request_made, time_response_made, time_finished) ) ;
93
+ // Ensure the request is flushed, any Transfer-Encoding completed, etc.
94
+ response. finish_response ( ) ;
95
+ let time_finished = precise_time_ns ( ) ;
96
+ child_perf_ch. send ( ( time_start, time_spawned, time_request_made, time_response_made, time_finished) ) ;
96
97
97
- // Subsequent requests on this connection have no spawn time
98
- time_start = time_finished;
98
+ // Subsequent requests on this connection have no spawn time
99
+ time_start = time_finished;
99
100
100
- if request. close_connection {
101
- break;
102
- }
103
- }
101
+ if request. close_connection {
102
+ break ;
104
103
}
105
104
}
106
105
}
0 commit comments