diff options
author | erdgeist <> | 2009-11-18 04:00:26 +0000 |
---|---|---|
committer | erdgeist <> | 2009-11-18 04:00:26 +0000 |
commit | f3c0359876b59aa8fc2f03fa61363ede9d2edc2f (patch) | |
tree | a7924f5d8ed72ac8f7c4d5f68987f2aea04f3450 /opentracker.c | |
parent | 90e7262d9d79b4098cbc52df549e138b77add193 (diff) |
Make header parsing more efficient, prepare multithreading and keep-alive.
Diffstat (limited to 'opentracker.c')
-rw-r--r-- | opentracker.c | 66 |
1 files changed, 30 insertions, 36 deletions
diff --git a/opentracker.c b/opentracker.c index c1fe945..57eca12 100644 --- a/opentracker.c +++ b/opentracker.c | |||
@@ -143,10 +143,8 @@ static size_t header_complete( char * request, ssize_t byte_count ) { | |||
143 | static void handle_dead( const int64 sock ) { | 143 | static void handle_dead( const int64 sock ) { |
144 | struct http_data* cookie=io_getcookie( sock ); | 144 | struct http_data* cookie=io_getcookie( sock ); |
145 | if( cookie ) { | 145 | if( cookie ) { |
146 | if( cookie->flag & STRUCT_HTTP_FLAG_IOB_USED ) | 146 | iob_reset( &cookie->batch ); |
147 | iob_reset( &cookie->data.batch ); | 147 | array_reset( &cookie->request ); |
148 | if( cookie->flag & STRUCT_HTTP_FLAG_ARRAY_USED ) | ||
149 | array_reset( &cookie->data.request ); | ||
150 | if( cookie->flag & STRUCT_HTTP_FLAG_WAITINGFORTASK ) | 148 | if( cookie->flag & STRUCT_HTTP_FLAG_WAITINGFORTASK ) |
151 | mutex_workqueue_canceltask( sock ); | 149 | mutex_workqueue_canceltask( sock ); |
152 | free( cookie ); | 150 | free( cookie ); |
@@ -154,46 +152,42 @@ static void handle_dead( const int64 sock ) { | |||
154 | io_close( sock ); | 152 | io_close( sock ); |
155 | } | 153 | } |
156 | 154 | ||
157 | static ssize_t handle_read( const int64 sock, struct ot_workstruct *ws ) { | 155 | static void handle_read( const int64 sock, struct ot_workstruct *ws ) { |
158 | struct http_data* cookie = io_getcookie( sock ); | 156 | struct http_data* cookie = io_getcookie( sock ); |
159 | ssize_t byte_count; | 157 | ssize_t byte_count; |
160 | 158 | ||
161 | if( ( byte_count = io_tryread( sock, ws->inbuf, G_INBUF_SIZE ) ) <= 0 ) { | 159 | if( ( byte_count = io_tryread( sock, ws->inbuf, G_INBUF_SIZE ) ) <= 0 ) { |
162 | handle_dead( sock ); | 160 | handle_dead( sock ); |
163 | return 0; | 161 | return; |
164 | } | 162 | } |
165 | 163 | ||
166 | /* If we get the whole request in one packet, handle it without copying */ | 164 | /* If we get the whole request in one packet, handle it without copying */ |
167 | if( !array_start( &cookie->data.request ) ) { | 165 | if( !array_start( &cookie->request ) ) { |
168 | if( memchr( ws->inbuf, '\n', byte_count ) ) { | 166 | if( ( ws->header_size = header_complete( ws->inbuf, byte_count ) ) ) { |
169 | ws->request = ws->inbuf; | 167 | ws->request = ws->inbuf; |
170 | ws->request_size = byte_count; | 168 | ws->request_size = byte_count; |
171 | return http_handle_request( sock, ws ); | 169 | http_handle_request( sock, ws ); |
172 | } | 170 | } else |
173 | 171 | array_catb( &cookie->request, ws->inbuf, byte_count ); | |
174 | /* ... else take a copy */ | 172 | return; |
175 | cookie->flag |= STRUCT_HTTP_FLAG_ARRAY_USED; | ||
176 | array_catb( &cookie->data.request, ws->inbuf, byte_count ); | ||
177 | return 0; | ||
178 | } | 173 | } |
179 | 174 | ||
180 | array_catb( &cookie->data.request, ws->inbuf, byte_count ); | 175 | array_catb( &cookie->request, ws->inbuf, byte_count ); |
181 | 176 | if( array_failed( &cookie->request ) || array_bytes( &cookie->request ) > 8192 ) { | |
182 | if( array_failed( &cookie->data.request ) || | 177 | http_issue_error( sock, ws, CODE_HTTPERROR_500 ); |
183 | array_bytes( &cookie->data.request ) > 8192 ) | 178 | return; |
184 | return http_issue_error( sock, ws, CODE_HTTPERROR_500 ); | 179 | } |
185 | |||
186 | if( !memchr( array_start( &cookie->data.request ), '\n', array_bytes( &cookie->data.request ) ) ) | ||
187 | return 0; | ||
188 | 180 | ||
189 | ws->request = array_start( &cookie->data.request ); | 181 | while( ( ws->header_size = header_complete( array_start( &cookie->request ), array_bytes( &cookie->request ) ) ) ) { |
190 | ws->request_size = array_bytes( &cookie->data.request ); | 182 | ws->request = array_start( &cookie->request ); |
191 | return http_handle_request( sock, ws ); | 183 | ws->request_size = array_bytes( &cookie->request ); |
184 | http_handle_request( sock, ws ); | ||
185 | } | ||
192 | } | 186 | } |
193 | 187 | ||
194 | static void handle_write( const int64 sock ) { | 188 | static void handle_write( const int64 sock ) { |
195 | struct http_data* cookie=io_getcookie( sock ); | 189 | struct http_data* cookie=io_getcookie( sock ); |
196 | if( !cookie || ( iob_send( sock, &cookie->data.batch ) <= 0 ) ) | 190 | if( !cookie || ( iob_send( sock, &cookie->batch ) <= 0 ) ) |
197 | handle_dead( sock ); | 191 | handle_dead( sock ); |
198 | } | 192 | } |
199 | 193 | ||
@@ -214,12 +208,12 @@ static void handle_accept( const int64 serversocket ) { | |||
214 | io_close( sock ); | 208 | io_close( sock ); |
215 | continue; | 209 | continue; |
216 | } | 210 | } |
217 | io_setcookie( sock, cookie ); | ||
218 | io_wantread( sock ); | ||
219 | |||
220 | memset(cookie, 0, sizeof( struct http_data ) ); | 211 | memset(cookie, 0, sizeof( struct http_data ) ); |
221 | memcpy(cookie->ip,ip,sizeof(ot_ip6)); | 212 | memcpy(cookie->ip,ip,sizeof(ot_ip6)); |
222 | 213 | ||
214 | io_setcookie( sock, cookie ); | ||
215 | io_wantread( sock ); | ||
216 | |||
223 | stats_issue_event( EVENT_ACCEPT, FLAG_TCP, (uintptr_t)ip); | 217 | stats_issue_event( EVENT_ACCEPT, FLAG_TCP, (uintptr_t)ip); |
224 | 218 | ||
225 | /* That breaks taia encapsulation. But there is no way to take system | 219 | /* That breaks taia encapsulation. But there is no way to take system |
@@ -228,17 +222,16 @@ static void handle_accept( const int64 serversocket ) { | |||
228 | tai_unix( &(t.sec), (g_now_seconds + OT_CLIENT_TIMEOUT) ); | 222 | tai_unix( &(t.sec), (g_now_seconds + OT_CLIENT_TIMEOUT) ); |
229 | io_timeout( sock, t ); | 223 | io_timeout( sock, t ); |
230 | } | 224 | } |
231 | |||
232 | if( errno == EAGAIN ) | ||
233 | io_eagain( serversocket ); | ||
234 | } | 225 | } |
235 | 226 | ||
236 | static void server_mainloop( ) { | 227 | static void * server_mainloop( void * args ) { |
237 | struct ot_workstruct ws; | 228 | struct ot_workstruct ws; |
238 | time_t next_timeout_check = g_now_seconds + OT_CLIENT_TIMEOUT_CHECKINTERVAL; | 229 | time_t next_timeout_check = g_now_seconds + OT_CLIENT_TIMEOUT_CHECKINTERVAL; |
239 | struct iovec *iovector; | 230 | struct iovec *iovector; |
240 | int iovec_entries; | 231 | int iovec_entries; |
241 | 232 | ||
233 | (void)args; | ||
234 | |||
242 | /* Initialize our "thread local storage" */ | 235 | /* Initialize our "thread local storage" */ |
243 | ws.inbuf = malloc( G_INBUF_SIZE ); | 236 | ws.inbuf = malloc( G_INBUF_SIZE ); |
244 | ws.outbuf = malloc( G_OUTBUF_SIZE ); | 237 | ws.outbuf = malloc( G_OUTBUF_SIZE ); |
@@ -282,6 +275,7 @@ static void server_mainloop( ) { | |||
282 | /* Enforce setting the clock */ | 275 | /* Enforce setting the clock */ |
283 | signal_handler( SIGALRM ); | 276 | signal_handler( SIGALRM ); |
284 | } | 277 | } |
278 | return 0; | ||
285 | } | 279 | } |
286 | 280 | ||
287 | static int64_t ot_try_bind( ot_ip6 ip, uint16_t port, PROTO_FLAG proto ) { | 281 | static int64_t ot_try_bind( ot_ip6 ip, uint16_t port, PROTO_FLAG proto ) { |
@@ -475,7 +469,7 @@ void load_state(const char * const state_filename ) { | |||
475 | if( inbuf[ i++ ] != ':' || !( consumed = scan_ulonglong( inbuf+i, &downcount ) ) ) continue; | 469 | if( inbuf[ i++ ] != ':' || !( consumed = scan_ulonglong( inbuf+i, &downcount ) ) ) continue; |
476 | add_torrent_from_saved_state( infohash, base, downcount ); | 470 | add_torrent_from_saved_state( infohash, base, downcount ); |
477 | } | 471 | } |
478 | 472 | ||
479 | fclose( state_filehandle ); | 473 | fclose( state_filehandle ); |
480 | } | 474 | } |
481 | 475 | ||
@@ -606,7 +600,7 @@ int main( int argc, char **argv ) { | |||
606 | /* Kick off our initial clock setting alarm */ | 600 | /* Kick off our initial clock setting alarm */ |
607 | alarm(5); | 601 | alarm(5); |
608 | 602 | ||
609 | server_mainloop( ); | 603 | server_mainloop( 0 ); |
610 | 604 | ||
611 | return 0; | 605 | return 0; |
612 | } | 606 | } |