diff options
Diffstat (limited to 'ot_http.c')
| -rw-r--r-- | ot_http.c | 38 |
1 files changed, 28 insertions, 10 deletions
| @@ -39,22 +39,30 @@ ssize_t g_stats_path_len; | |||
| 39 | 39 | ||
| 40 | enum { SUCCESS_HTTP_HEADER_LENGTH = 80, SUCCESS_HTTP_SIZE_OFF = 17 }; | 40 | enum { SUCCESS_HTTP_HEADER_LENGTH = 80, SUCCESS_HTTP_SIZE_OFF = 17 }; |
| 41 | 41 | ||
| 42 | int http_adopt(const int64_t sock, struct http_data *cookie) { | 42 | struct http_data *http_adopt(const int64_t sock) { |
| 43 | struct http_data *heap = malloc(sizeof(*heap)); | 43 | struct http_data *cookie = fdstate_cookie(sock), *heap; |
| 44 | int interest; | ||
| 44 | 45 | ||
| 45 | if (!heap) | 46 | if (!cookie || !(cookie->flag & STRUCT_HTTP_FLAG_ONSTACK)) |
| 46 | return -1; | 47 | return cookie; |
| 48 | |||
| 49 | if (!(heap = malloc(sizeof(*heap)))) | ||
| 50 | return NULL; | ||
| 47 | 51 | ||
| 48 | *heap = *cookie; | 52 | *heap = *cookie; |
| 49 | heap->flag &= ~STRUCT_HTTP_FLAG_ONSTACK; | 53 | heap->flag &= ~STRUCT_HTTP_FLAG_ONSTACK; |
| 54 | |||
| 55 | /* Publishing the cookie is what lets another thread reach this connection, | ||
| 56 | so nothing may touch it afterwards, not even to read what it asked for */ | ||
| 57 | interest = heap->interest; | ||
| 50 | fdstate_set_cookie((int)sock, heap); | 58 | fdstate_set_cookie((int)sock, heap); |
| 51 | 59 | ||
| 52 | if (event_add((int)sock, heap->interest, fdstate_generation((int)sock)) == -1) { | 60 | if (event_add((int)sock, interest, fdstate_generation((int)sock)) == -1) { |
| 53 | fdstate_set_cookie((int)sock, cookie); | 61 | fdstate_set_cookie((int)sock, cookie); |
| 54 | free(heap); | 62 | free(heap); |
| 55 | return -1; | 63 | return NULL; |
| 56 | } | 64 | } |
| 57 | return 0; | 65 | return heap; |
| 58 | } | 66 | } |
| 59 | 67 | ||
| 60 | /* Give up a connection: the one place that knows everything hanging off it. */ | 68 | /* Give up a connection: the one place that knows everything hanging off it. */ |
| @@ -348,13 +356,17 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c | |||
| 348 | } | 356 | } |
| 349 | #endif | 357 | #endif |
| 350 | #endif | 358 | #endif |
| 351 | /* Pass this task to the worker thread */ | ||
| 352 | cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK | STRUCT_HTTP_FLAG_CHUNKED; | 359 | cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK | STRUCT_HTTP_FLAG_CHUNKED; |
| 353 | 360 | ||
| 354 | /* Clients waiting for us should not easily timeout */ | 361 | /* Clients waiting for us should not easily timeout */ |
| 355 | fdstate_set_expiry(sock, 0); | 362 | fdstate_set_expiry(sock, 0); |
| 356 | fullscrape_deliver(sock, format); | ||
| 357 | http_interest_set(sock, cookie, 0); | 363 | http_interest_set(sock, cookie, 0); |
| 364 | |||
| 365 | /* Everything this connection needs has been written, so it can be given | ||
| 366 | a home of its own and only then be made reachable by a worker thread */ | ||
| 367 | if (!http_adopt(sock)) | ||
| 368 | HTTPERROR_500; | ||
| 369 | fullscrape_deliver(sock, format); | ||
| 358 | return ws->reply_size = -2; | 370 | return ws->reply_size = -2; |
| 359 | } | 371 | } |
| 360 | #endif | 372 | #endif |
| @@ -366,6 +378,9 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c | |||
| 366 | 378 | ||
| 367 | /* Complex stats also include expensive memory debugging tools */ | 379 | /* Complex stats also include expensive memory debugging tools */ |
| 368 | fdstate_set_expiry(sock, 0); | 380 | fdstate_set_expiry(sock, 0); |
| 381 | |||
| 382 | if (!http_adopt(sock)) | ||
| 383 | HTTPERROR_500; | ||
| 369 | stats_deliver(sock, mode); | 384 | stats_deliver(sock, mode); |
| 370 | return ws->reply_size = -2; | 385 | return ws->reply_size = -2; |
| 371 | } | 386 | } |
| @@ -448,8 +463,11 @@ static ssize_t http_handle_fullscrape(const int64_t sock, struct ot_workstruct * | |||
| 448 | cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK | STRUCT_HTTP_FLAG_CHUNKED; | 463 | cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK | STRUCT_HTTP_FLAG_CHUNKED; |
| 449 | /* Clients waiting for us should not easily timeout */ | 464 | /* Clients waiting for us should not easily timeout */ |
| 450 | fdstate_set_expiry(sock, 0); | 465 | fdstate_set_expiry(sock, 0); |
| 451 | fullscrape_deliver(sock, format); | ||
| 452 | http_interest_set(sock, cookie, 0); | 466 | http_interest_set(sock, cookie, 0); |
| 467 | |||
| 468 | if (!http_adopt(sock)) | ||
| 469 | HTTPERROR_500; | ||
| 470 | fullscrape_deliver(sock, format); | ||
| 453 | return ws->reply_size = -2; | 471 | return ws->reply_size = -2; |
| 454 | } | 472 | } |
| 455 | #endif | 473 | #endif |
