diff options
Diffstat (limited to 'opentracker.c')
| -rw-r--r-- | opentracker.c | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/opentracker.c b/opentracker.c index 6271b9e..a546fc5 100644 --- a/opentracker.c +++ b/opentracker.c | |||
| @@ -40,18 +40,21 @@ | |||
| 40 | 40 | ||
| 41 | /* Globals */ | 41 | /* Globals */ |
| 42 | uint32_t g_tracker_id; | 42 | uint32_t g_tracker_id; |
| 43 | volatile int g_opentracker_running = 1; | 43 | _Atomic int g_opentracker_running = 1; |
| 44 | int g_self_pipe[2]; | 44 | int g_self_pipe[2]; |
| 45 | 45 | ||
| 46 | |||
| 47 | static void panic(const char *routine) __attribute__((noreturn)); | 46 | static void panic(const char *routine) __attribute__((noreturn)); |
| 48 | static void panic(const char *routine) { | 47 | static void panic(const char *routine) { |
| 49 | fprintf(stderr, "%s: %s\n", routine, strerror(errno)); | 48 | fprintf(stderr, "%s: %s\n", routine, strerror(errno)); |
| 50 | exit(111); | 49 | exit(111); |
| 51 | } | 50 | } |
| 52 | 51 | ||
| 52 | /* Say we are stopping, wake the loop, and let main do the work on its own stack. */ | ||
| 53 | static void signal_handler(int s) { | 53 | static void signal_handler(int s) { |
| 54 | if (s == SIGINT) { | 54 | if (s == SIGINT) { |
| 55 | const char byte = 0; | ||
| 56 | int saved = errno; | ||
| 57 | |||
| 55 | /* Any new interrupt signal quits the application */ | 58 | /* Any new interrupt signal quits the application */ |
| 56 | signal(SIGINT, SIG_DFL); | 59 | signal(SIGINT, SIG_DFL); |
| 57 | 60 | ||
| @@ -59,13 +62,8 @@ static void signal_handler(int s) { | |||
| 59 | but cancel their operations and return */ | 62 | but cancel their operations and return */ |
| 60 | g_opentracker_running = 0; | 63 | g_opentracker_running = 0; |
| 61 | 64 | ||
| 62 | trackerlogic_deinit(); | 65 | (void)!write(g_self_pipe[1], &byte, 1); |
| 63 | 66 | errno = saved; | |
| 64 | #ifdef WANT_SYSLOGS | ||
| 65 | closelog(); | ||
| 66 | #endif | ||
| 67 | |||
| 68 | exit(0); | ||
| 69 | } | 67 | } |
| 70 | } | 68 | } |
| 71 | 69 | ||
| @@ -86,7 +84,7 @@ static void install_signal_handlers(void) { | |||
| 86 | 84 | ||
| 87 | sa.sa_handler = signal_handler; | 85 | sa.sa_handler = signal_handler; |
| 88 | sigemptyset(&sa.sa_mask); | 86 | sigemptyset(&sa.sa_mask); |
| 89 | sa.sa_flags = SA_RESTART; | 87 | sa.sa_flags = 0; |
| 90 | if ((sigaction(SIGINT, &sa, NULL) == -1) || (sigaction(SIGALRM, &sa, NULL) == -1)) | 88 | if ((sigaction(SIGINT, &sa, NULL) == -1) || (sigaction(SIGALRM, &sa, NULL) == -1)) |
| 91 | panic("install_signal_handlers"); | 89 | panic("install_signal_handlers"); |
| 92 | 90 | ||
| @@ -207,7 +205,7 @@ static void handle_write(const int64_t sock) { | |||
| 207 | handle_dead(sock); | 205 | handle_dead(sock); |
| 208 | } | 206 | } |
| 209 | 207 | ||
| 210 | static void handle_accept(const int64_t serversocket) { | 208 | static void handle_accept(const int64_t serversocket, struct ot_workstruct *ws) { |
| 211 | struct http_data *cookie; | 209 | struct http_data *cookie; |
| 212 | int64_t sock; | 210 | int64_t sock; |
| 213 | ot_ip6 ip; | 211 | ot_ip6 ip; |
| @@ -217,11 +215,10 @@ static void handle_accept(const int64_t serversocket) { | |||
| 217 | 215 | ||
| 218 | socket_set_blocking((int)sock, 0); | 216 | socket_set_blocking((int)sock, 0); |
| 219 | 217 | ||
| 220 | if (!(cookie = (struct http_data *)malloc(sizeof(struct http_data)))) { | 218 | if (!(cookie = (struct http_data *)calloc(1, sizeof(struct http_data)))) { |
| 221 | close((int)sock); | 219 | close((int)sock); |
| 222 | continue; | 220 | continue; |
| 223 | } | 221 | } |
| 224 | memset(cookie, 0, sizeof(struct http_data)); | ||
| 225 | memcpy(cookie->ip, ip, sizeof(ot_ip6)); | 222 | memcpy(cookie->ip, ip, sizeof(ot_ip6)); |
| 226 | cookie->interest = EVENT_IN; | 223 | cookie->interest = EVENT_IN; |
| 227 | 224 | ||
| @@ -232,7 +229,7 @@ static void handle_accept(const int64_t serversocket) { | |||
| 232 | continue; | 229 | continue; |
| 233 | } | 230 | } |
| 234 | 231 | ||
| 235 | stats_issue_event(EVENT_ACCEPT, FLAG_TCP, (uintptr_t)ip); | 232 | stats_issue_event(ws, EVENT_ACCEPT, FLAG_TCP, (uintptr_t)ip); |
| 236 | } | 233 | } |
| 237 | } | 234 | } |
| 238 | 235 | ||
| @@ -249,6 +246,8 @@ static void *server_mainloop(void *args) { | |||
| 249 | (void)args; | 246 | (void)args; |
| 250 | 247 | ||
| 251 | /* Initialize our "thread local storage" */ | 248 | /* Initialize our "thread local storage" */ |
| 249 | memset(&ws, 0, sizeof(ws)); | ||
| 250 | stats_counters_register(&ws); | ||
| 252 | ws.inbuf = malloc(G_INBUF_SIZE); | 251 | ws.inbuf = malloc(G_INBUF_SIZE); |
| 253 | ws.outbuf = malloc(G_OUTBUF_SIZE); | 252 | ws.outbuf = malloc(G_OUTBUF_SIZE); |
| 254 | #ifdef _DEBUG_HTTPERROR | 253 | #ifdef _DEBUG_HTTPERROR |
| @@ -260,7 +259,7 @@ static void *server_mainloop(void *args) { | |||
| 260 | 259 | ||
| 261 | random_bytes(ws.rand48_state, sizeof(ws.rand48_state)); | 260 | random_bytes(ws.rand48_state, sizeof(ws.rand48_state)); |
| 262 | 261 | ||
| 263 | for (;;) { | 262 | while (g_opentracker_running) { |
| 264 | ot_event ready[OT_EVENT_BATCH]; | 263 | ot_event ready[OT_EVENT_BATCH]; |
| 265 | int64_t sock; | 264 | int64_t sock; |
| 266 | int count, i; | 265 | int count, i; |
| @@ -279,7 +278,7 @@ static void *server_mainloop(void *args) { | |||
| 279 | cookie = fdstate_cookie((int)sock); | 278 | cookie = fdstate_cookie((int)sock); |
| 280 | 279 | ||
| 281 | if ((intptr_t)cookie == FLAG_TCP) | 280 | if ((intptr_t)cookie == FLAG_TCP) |
| 282 | handle_accept(sock); | 281 | handle_accept(sock, &ws); |
| 283 | else if ((intptr_t)cookie == FLAG_UDP) | 282 | else if ((intptr_t)cookie == FLAG_UDP) |
| 284 | handle_udp6(sock, &ws); | 283 | handle_udp6(sock, &ws); |
| 285 | else if ((intptr_t)cookie == FLAG_SELFPIPE) | 284 | else if ((intptr_t)cookie == FLAG_SELFPIPE) |
| @@ -297,16 +296,26 @@ static void *server_mainloop(void *args) { | |||
| 297 | while ((sock = mutex_workqueue_popresult(&iovec_entries, &iovector, &is_partial)) != -1) | 296 | while ((sock = mutex_workqueue_popresult(&iovec_entries, &iovector, &is_partial)) != -1) |
| 298 | http_sendiovecdata(sock, &ws, iovec_entries, iovector, is_partial); | 297 | http_sendiovecdata(sock, &ws, iovec_entries, iovector, is_partial); |
| 299 | 298 | ||
| 300 | if (g_now_seconds > next_timeout_check) { | 299 | if (time_now_seconds() > next_timeout_check) { |
| 301 | int cursor = 0; | 300 | int cursor = 0; |
| 302 | 301 | ||
| 303 | while ((sock = fdstate_next_expired(g_now_seconds, &cursor)) != -1) | 302 | while ((sock = fdstate_next_expired(time_now_seconds(), &cursor)) != -1) |
| 304 | handle_dead(sock); | 303 | handle_dead(sock); |
| 305 | next_timeout_check = g_now_seconds + OT_CLIENT_TIMEOUT_CHECKINTERVAL; | 304 | next_timeout_check = time_future_seconds(OT_CLIENT_TIMEOUT_CHECKINTERVAL); |
| 306 | } | 305 | } |
| 307 | 306 | ||
| 308 | livesync_ticker(); | 307 | livesync_ticker(); |
| 309 | } | 308 | } |
| 309 | |||
| 310 | /* This work struct is about to go out of scope, so hand its tally over | ||
| 311 | before anything can read it there */ | ||
| 312 | stats_counters_retire(&ws); | ||
| 313 | |||
| 314 | free(ws.inbuf); | ||
| 315 | free(ws.outbuf); | ||
| 316 | #ifdef _DEBUG_HTTPERROR | ||
| 317 | free(ws.debugbuf); | ||
| 318 | #endif | ||
| 310 | return 0; | 319 | return 0; |
| 311 | } | 320 | } |
| 312 | 321 | ||
| @@ -511,6 +520,13 @@ int main(int argc, char **argv) { | |||
| 511 | 520 | ||
| 512 | server_mainloop(0); | 521 | server_mainloop(0); |
| 513 | 522 | ||
| 523 | /* The loop has left, so no thread is serving any more and the teardown | ||
| 524 | can run where a debugger and the sanitizers can follow it */ | ||
| 525 | trackerlogic_deinit(); | ||
| 526 | #ifdef WANT_SYSLOGS | ||
| 527 | closelog(); | ||
| 528 | #endif | ||
| 529 | |||
| 514 | event_deinit(); | 530 | event_deinit(); |
| 515 | fdstate_deinit(); | 531 | fdstate_deinit(); |
| 516 | return 0; | 532 | return 0; |
