diff options
author | erdgeist <> | 2009-01-05 18:05:39 +0000 |
---|---|---|
committer | erdgeist <> | 2009-01-05 18:05:39 +0000 |
commit | 779d6c235ff8fe5284fd10dc82a9b99e7fa38d06 (patch) | |
tree | 043369d2a98a45b902e5d0968e28d78c1771b143 /opentracker.c | |
parent | 8bdc0d73f6f0bcaf83b7fb3d39e79e8fa4e6050d (diff) |
* http and udp routines now use thread local buffers passed in workstruct containers. In other words they do not use static_buffer anymore and are considered to be thread safe.
* the new workstruct also introduces a well defined buffer and result passing path
* a new function scan_find_keywords is a wrapper around scan_urlencoded_query that maps keys in url to values passed in an array of ot_keywords structs
* this new function cleans up much of url parameter parsing work, where read_ptr and write_ptr have been introduced rather than the confusing char *c, *data variables
* I now use memcmp instead of byte_diff to allow compiler to optimize constant size string compares
* got rid of UTORRENT_1600_WORKAROUND
* livesync_ticker is now only called from one (currently main) thread to avoid race conditions
Diffstat (limited to 'opentracker.c')
-rw-r--r-- | opentracker.c | 67 |
1 files changed, 46 insertions, 21 deletions
diff --git a/opentracker.c b/opentracker.c index bce5be0..8a4126c 100644 --- a/opentracker.c +++ b/opentracker.c | |||
@@ -41,9 +41,6 @@ volatile int g_opentracker_running = 1; | |||
41 | 41 | ||
42 | static char * g_serverdir = NULL; | 42 | static char * g_serverdir = NULL; |
43 | 43 | ||
44 | /* To always have space for error messages ;) */ | ||
45 | static char static_inbuf[8192]; | ||
46 | |||
47 | static void panic( const char *routine ) { | 44 | static void panic( const char *routine ) { |
48 | fprintf( stderr, "%s: %s\n", routine, strerror(errno) ); | 45 | fprintf( stderr, "%s: %s\n", routine, strerror(errno) ); |
49 | exit( 111 ); | 46 | exit( 111 ); |
@@ -107,37 +104,44 @@ static void handle_dead( const int64 socket ) { | |||
107 | io_close( socket ); | 104 | io_close( socket ); |
108 | } | 105 | } |
109 | 106 | ||
110 | static ssize_t handle_read( const int64 clientsocket ) { | 107 | static ssize_t handle_read( const int64 clientsocket, struct ot_workstruct *ws ) { |
111 | struct http_data* h = io_getcookie( clientsocket ); | 108 | struct http_data* h = io_getcookie( clientsocket ); |
112 | ssize_t l; | 109 | ssize_t l; |
113 | 110 | ||
114 | if( ( l = io_tryread( clientsocket, static_inbuf, sizeof static_inbuf ) ) <= 0 ) { | 111 | if( ( l = io_tryread( clientsocket, ws->inbuf, ws->inbuf_size ) ) <= 0 ) { |
115 | handle_dead( clientsocket ); | 112 | handle_dead( clientsocket ); |
116 | return 0; | 113 | return 0; |
117 | } | 114 | } |
118 | 115 | ||
119 | /* If we get the whole request in one packet, handle it without copying */ | 116 | /* If we get the whole request in one packet, handle it without copying */ |
120 | if( !array_start( &h->data.request ) ) { | 117 | if( !array_start( &h->data.request ) ) { |
121 | if( memchr( static_inbuf, '\n', l ) ) | 118 | if( memchr( ws->inbuf, '\n', l ) ) { |
122 | return http_handle_request( clientsocket, static_inbuf, l ); | 119 | ws->request = ws->inbuf; |
120 | ws->request_size = l; | ||
121 | return http_handle_request( clientsocket, ws ); | ||
122 | } | ||
123 | |||
124 | /* ... else take a copy */ | ||
123 | h->flag |= STRUCT_HTTP_FLAG_ARRAY_USED; | 125 | h->flag |= STRUCT_HTTP_FLAG_ARRAY_USED; |
124 | array_catb( &h->data.request, static_inbuf, l ); | 126 | array_catb( &h->data.request, ws->inbuf, l ); |
125 | return 0; | 127 | return 0; |
126 | } | 128 | } |
127 | 129 | ||
128 | h->flag |= STRUCT_HTTP_FLAG_ARRAY_USED; | 130 | h->flag |= STRUCT_HTTP_FLAG_ARRAY_USED; |
129 | array_catb( &h->data.request, static_inbuf, l ); | 131 | array_catb( &h->data.request, ws->inbuf, l ); |
130 | 132 | ||
131 | if( array_failed( &h->data.request ) ) | 133 | if( array_failed( &h->data.request ) ) |
132 | return http_issue_error( clientsocket, CODE_HTTPERROR_500 ); | 134 | return http_issue_error( clientsocket, ws, CODE_HTTPERROR_500 ); |
133 | 135 | ||
134 | if( array_bytes( &h->data.request ) > 8192 ) | 136 | if( array_bytes( &h->data.request ) > 8192 ) |
135 | return http_issue_error( clientsocket, CODE_HTTPERROR_500 ); | 137 | return http_issue_error( clientsocket, ws, CODE_HTTPERROR_500 ); |
136 | 138 | ||
137 | if( memchr( array_start( &h->data.request ), '\n', array_bytes( &h->data.request ) ) ) | 139 | if( !memchr( array_start( &h->data.request ), '\n', array_bytes( &h->data.request ) ) ) |
138 | return http_handle_request( clientsocket, array_start( &h->data.request ), array_bytes( &h->data.request ) ); | 140 | return 0; |
139 | 141 | ||
140 | return 0; | 142 | ws->request = array_start( &h->data.request ); |
143 | ws->request_size = array_bytes( &h->data.request ); | ||
144 | return http_handle_request( clientsocket, ws ); | ||
141 | } | 145 | } |
142 | 146 | ||
143 | static void handle_write( const int64 clientsocket ) { | 147 | static void handle_write( const int64 clientsocket ) { |
@@ -183,9 +187,25 @@ static void handle_accept( const int64 serversocket ) { | |||
183 | } | 187 | } |
184 | 188 | ||
185 | static void server_mainloop( ) { | 189 | static void server_mainloop( ) { |
186 | time_t next_timeout_check = g_now_seconds + OT_CLIENT_TIMEOUT_CHECKINTERVAL; | 190 | struct ot_workstruct ws; |
187 | struct iovec *iovector; | 191 | time_t next_timeout_check = g_now_seconds + OT_CLIENT_TIMEOUT_CHECKINTERVAL; |
188 | int iovec_entries; | 192 | struct iovec *iovector; |
193 | int iovec_entries; | ||
194 | |||
195 | /* Initialize our "thread local storage" */ | ||
196 | ws.inbuf = malloc( THREAD_INBUF_SIZE ); | ||
197 | ws.outbuf = malloc( THREAD_OUTBUF_SIZE ); | ||
198 | #ifdef _DEBUG_HTTPERROR | ||
199 | ws.debugbuf= malloc( THREAD_INBUF_SIZE ); | ||
200 | #endif | ||
201 | if( !ws.inbuf || !ws.outbuf ) | ||
202 | panic( "Initializing worker failed" ); | ||
203 | |||
204 | ws.inbuf_size = THREAD_INBUF_SIZE; | ||
205 | ws.outbuf_size = THREAD_OUTBUF_SIZE; | ||
206 | #ifdef _DEBUG_HTTPERROR | ||
207 | ws.debugbuf_size= THREAD_INBUF_SIZE; | ||
208 | #endif | ||
189 | 209 | ||
190 | for( ; ; ) { | 210 | for( ; ; ) { |
191 | int64 i; | 211 | int64 i; |
@@ -197,13 +217,13 @@ static void server_mainloop( ) { | |||
197 | if( (intptr_t)cookie == FLAG_TCP ) | 217 | if( (intptr_t)cookie == FLAG_TCP ) |
198 | handle_accept( i ); | 218 | handle_accept( i ); |
199 | else if( (intptr_t)cookie == FLAG_UDP ) | 219 | else if( (intptr_t)cookie == FLAG_UDP ) |
200 | handle_udp4( i ); | 220 | handle_udp4( i, &ws ); |
201 | else | 221 | else |
202 | handle_read( i ); | 222 | handle_read( i, &ws ); |
203 | } | 223 | } |
204 | 224 | ||
205 | while( ( i = mutex_workqueue_popresult( &iovec_entries, &iovector ) ) != -1 ) | 225 | while( ( i = mutex_workqueue_popresult( &iovec_entries, &iovector ) ) != -1 ) |
206 | http_sendiovecdata( i, iovec_entries, iovector ); | 226 | http_sendiovecdata( i, &ws, iovec_entries, iovector ); |
207 | 227 | ||
208 | while( ( i = io_canwrite( ) ) != -1 ) | 228 | while( ( i = io_canwrite( ) ) != -1 ) |
209 | handle_write( i ); | 229 | handle_write( i ); |
@@ -431,7 +451,12 @@ while( scanon ) { | |||
431 | break; | 451 | break; |
432 | case 'f': bound += parse_configfile( optarg ); break; | 452 | case 'f': bound += parse_configfile( optarg ); break; |
433 | case 'h': help( argv[0] ); exit( 0 ); | 453 | case 'h': help( argv[0] ); exit( 0 ); |
434 | case 'v': stats_return_tracker_version( static_inbuf ); fputs( static_inbuf, stderr ); exit( 0 ); | 454 | case 'v': { |
455 | char buffer[8192]; | ||
456 | stats_return_tracker_version( buffer ); | ||
457 | fputs( buffer, stderr ); | ||
458 | exit( 0 ); | ||
459 | } | ||
435 | default: | 460 | default: |
436 | case '?': usage( argv[0] ); exit( 1 ); | 461 | case '?': usage( argv[0] ); exit( 1 ); |
437 | } | 462 | } |