Changeset fa84adfbc712fa0e327aa3ba60ccb09632d36fb0
- Timestamp:
- 05/22/10 18:29:54
(3 years ago)
- Author:
- Theo Schlossnagle <jesus@omniti.com>
- git-committer:
- Theo Schlossnagle <jesus@omniti.com> 1274552994 +0000
- git-parent:
[95ab72aecaf4b9fe59777d61465217590bfab3a4]
- git-author:
- Theo Schlossnagle <jesus@omniti.com> 1274552994 +0000
- Message:
sigificant updates around cleaning up memory, refs #281
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r30339cd |
rfa84adf |
|
| 77 | 77 | } |
|---|
| 78 | 78 | |
|---|
| 79 | | struct bchain *bchain_alloc(size_t size) { |
|---|
| | 79 | struct bchain *bchain_alloc(size_t size, int line) { |
|---|
| 80 | 80 | struct bchain *n; |
|---|
| 81 | 81 | n = malloc(size + ((char *)n->buff - (char *)n)); |
|---|
| | 82 | /*noitL(noit_error, "bchain_alloc(%p) : %d\n", n, line);*/ |
|---|
| 82 | 83 | if(!n) return NULL; |
|---|
| 83 | 84 | n->prev = n->next = NULL; |
|---|
| … | … | |
| 86 | 87 | return n; |
|---|
| 87 | 88 | } |
|---|
| | 89 | void bchain_free(struct bchain *b, int line) { |
|---|
| | 90 | /*noitL(noit_error, "bchain_free(%p) : %d\n", b, line);*/ |
|---|
| | 91 | free(b); |
|---|
| | 92 | } |
|---|
| | 93 | #define ALLOC_BCHAIN(s) bchain_alloc(s, __LINE__) |
|---|
| | 94 | #define FREE_BCHAIN(a) bchain_free(a, __LINE__) |
|---|
| 88 | 95 | #define RELEASE_BCHAIN(a) do { \ |
|---|
| 89 | 96 | while(a) { \ |
|---|
| … | … | |
| 91 | 98 | __b = a; \ |
|---|
| 92 | 99 | a = __b->next; \ |
|---|
| 93 | | bchain_free(__b); \ |
|---|
| | 100 | bchain_free(__b, __LINE__); \ |
|---|
| 94 | 101 | } \ |
|---|
| 95 | 102 | } while(0) |
|---|
| 96 | 103 | struct bchain *bchain_from_data(const void *d, size_t size) { |
|---|
| 97 | 104 | struct bchain *n; |
|---|
| 98 | | n = bchain_alloc(size); |
|---|
| | 105 | n = ALLOC_BCHAIN(size); |
|---|
| 99 | 106 | if(!n) return NULL; |
|---|
| 100 | 107 | memcpy(n->buff, d, size); |
|---|
| 101 | 108 | n->size = size; |
|---|
| 102 | 109 | return n; |
|---|
| 103 | | } |
|---|
| 104 | | void bchain_free(struct bchain *b) { |
|---|
| 105 | | free(b); |
|---|
| 106 | 110 | } |
|---|
| 107 | 111 | |
|---|
| … | … | |
| 165 | 169 | new_size = end_in_f + (b->start + b->size - start_in_b); |
|---|
| 166 | 170 | if(new_size > DEFAULT_BCHAINSIZE) return noit_false; /* string too long */ |
|---|
| 167 | | f = bchain_alloc(new_size); |
|---|
| | 171 | f = ALLOC_BCHAIN(new_size); |
|---|
| 168 | 172 | f->prev = b; |
|---|
| 169 | 173 | f->next = b->next; |
|---|
| … | … | |
| 246 | 250 | if(ctx->res.output_raw_offset >= b->size) { |
|---|
| 247 | 251 | *head = b->next; |
|---|
| 248 | | bchain_free(b); |
|---|
| | 252 | FREE_BCHAIN(b); |
|---|
| 249 | 253 | b = *head; |
|---|
| 250 | 254 | if(b) b->prev = NULL; |
|---|
| … | … | |
| 327 | 331 | int lsize = req->current_input->size - req->current_offset; |
|---|
| 328 | 332 | noitL(http_debug, " noit_http_request_finalize -- leftovers: %d\n", lsize); |
|---|
| 329 | | req->first_input = bchain_alloc(lsize); |
|---|
| | 333 | req->first_input = ALLOC_BCHAIN(lsize); |
|---|
| 330 | 334 | req->first_input->prev = NULL; |
|---|
| 331 | 335 | req->first_input->next = req->current_input->next; |
|---|
| … | … | |
| 339 | 343 | req->last_input = req->first_input; |
|---|
| 340 | 344 | else |
|---|
| 341 | | bchain_free(req->current_input); |
|---|
| | 345 | FREE_BCHAIN(req->current_input); |
|---|
| 342 | 346 | } |
|---|
| 343 | 347 | else { |
|---|
| … | … | |
| 404 | 408 | l1 = strlen(prefix); |
|---|
| 405 | 409 | l2 = strlen(value); |
|---|
| 406 | | b = bchain_alloc(l1 + l2 + 2); |
|---|
| | 410 | b = ALLOC_BCHAIN(l1 + l2 + 2); |
|---|
| 407 | 411 | b->next = req->current_request_chain; |
|---|
| 408 | 412 | b->next->prev = b; |
|---|
| … | … | |
| 511 | 515 | if(!in) { |
|---|
| 512 | 516 | in = ctx->req.first_input = ctx->req.last_input = |
|---|
| 513 | | bchain_alloc(DEFAULT_BCHAINSIZE); |
|---|
| | 517 | ALLOC_BCHAIN(DEFAULT_BCHAINSIZE); |
|---|
| 514 | 518 | if(!in) goto full_error; |
|---|
| 515 | 519 | } |
|---|
| … | … | |
| 518 | 522 | DEFAULT_BCHAINMINREAD < DEFAULT_BCHAINSIZE) { /* and we can */ |
|---|
| 519 | 523 | in->next = ctx->req.last_input = |
|---|
| 520 | | bchain_alloc(DEFAULT_BCHAINSIZE); |
|---|
| | 524 | ALLOC_BCHAIN(DEFAULT_BCHAINSIZE); |
|---|
| 521 | 525 | in->next->prev = in; |
|---|
| 522 | 526 | in = in->next; |
|---|
| … | … | |
| 556 | 560 | if(len > DEFAULT_BCHAINSIZE) return noit_false; |
|---|
| 557 | 561 | ctx->req.first_input = ctx->req.last_input = |
|---|
| 558 | | bchain_alloc(DEFAULT_BCHAINSIZE); |
|---|
| | 562 | ALLOC_BCHAIN(DEFAULT_BCHAINSIZE); |
|---|
| 559 | 563 | memcpy(ctx->req.first_input->buff, data, len); |
|---|
| 560 | 564 | ctx->req.first_input->size = len; |
|---|
| … | … | |
| 576 | 580 | RELEASE_BCHAIN(ctx->req.current_request_chain); |
|---|
| 577 | 581 | if(ctx->req.orig_qs) free(ctx->req.orig_qs); |
|---|
| 578 | | memset(&ctx->req, 0, sizeof(ctx->req)); |
|---|
| | 582 | memset(&ctx->req.state, 0, |
|---|
| | 583 | sizeof(ctx->req) - (unsigned long)&(((noit_http_request *)0)->state)); |
|---|
| 579 | 584 | } |
|---|
| 580 | 585 | void |
|---|
| … | … | |
| 591 | 596 | if(noit_atomic_dec32(&ctx->ref_cnt) == 0) { |
|---|
| 592 | 597 | noit_http_request_release(ctx); |
|---|
| | 598 | if(ctx->req.first_input) RELEASE_BCHAIN(ctx->req.first_input); |
|---|
| 593 | 599 | noit_http_response_release(ctx); |
|---|
| 594 | 600 | free(ctx); |
|---|
| 595 | 601 | } |
|---|
| | 602 | } |
|---|
| | 603 | void |
|---|
| | 604 | noit_http_ctx_acceptor_free(void *v) { |
|---|
| | 605 | noit_http_ctx_session_release((noit_http_session_ctx *)v); |
|---|
| 596 | 606 | } |
|---|
| 597 | 607 | int |
|---|
| … | … | |
| 636 | 646 | if(!in) |
|---|
| 637 | 647 | in = ctx->req.first_input = ctx->req.last_input = |
|---|
| 638 | | bchain_alloc(DEFAULT_BCHAINSIZE); |
|---|
| | 648 | ALLOC_BCHAIN(DEFAULT_BCHAINSIZE); |
|---|
| 639 | 649 | else if(in->start + in->size >= in->allocd) { |
|---|
| 640 | | in->next = bchain_alloc(DEFAULT_BCHAINSIZE); |
|---|
| | 650 | in->next = ALLOC_BCHAIN(DEFAULT_BCHAINSIZE); |
|---|
| 641 | 651 | in = ctx->req.last_input = in->next; |
|---|
| 642 | 652 | } |
|---|
| … | … | |
| 670 | 680 | int |
|---|
| 671 | 681 | noit_http_session_drive(eventer_t e, int origmask, void *closure, |
|---|
| 672 | | struct timeval *now) { |
|---|
| | 682 | struct timeval *now, int *done) { |
|---|
| 673 | 683 | noit_http_session_ctx *ctx = closure; |
|---|
| 674 | 684 | int rv = 0; |
|---|
| … | … | |
| 726 | 736 | abort_drive: |
|---|
| 727 | 737 | noit_http_log_request(ctx); |
|---|
| 728 | | ctx->conn.e->opset->close(ctx->conn.e->fd, &mask, ctx->conn.e); |
|---|
| 729 | | ctx->conn.e = NULL; |
|---|
| | 738 | if(ctx->conn.e) { |
|---|
| | 739 | ctx->conn.e->opset->close(ctx->conn.e->fd, &mask, ctx->conn.e); |
|---|
| | 740 | ctx->conn.e = NULL; |
|---|
| | 741 | } |
|---|
| 730 | 742 | goto release; |
|---|
| 731 | 743 | } |
|---|
| … | … | |
| 741 | 753 | } |
|---|
| 742 | 754 | noitL(http_debug, " <- noit_http_session_drive(%d) [%x]\n", e->fd, 0); |
|---|
| 743 | | return 0; |
|---|
| | 755 | goto abort_drive; |
|---|
| | 756 | |
|---|
| 744 | 757 | release: |
|---|
| | 758 | *done = 1; |
|---|
| | 759 | /* We're about to release, unhook us from the acceptor_closure so we |
|---|
| | 760 | * don't get double freed */ |
|---|
| | 761 | if(ctx->ac->service_ctx == ctx) ctx->ac->service_ctx = NULL; |
|---|
| 745 | 762 | noit_http_ctx_session_release(ctx); |
|---|
| 746 | 763 | noitL(http_debug, " <- noit_http_session_drive(%d) [%x]\n", e->fd, 0); |
|---|
| … | … | |
| 758 | 775 | ctx->dispatcher = f; |
|---|
| 759 | 776 | ctx->dispatcher_closure = c; |
|---|
| 760 | | ctx->drive = noit_http_session_drive; |
|---|
| 761 | 777 | ctx->ac = ac; |
|---|
| 762 | 778 | return ctx; |
|---|
| … | … | |
| 826 | 842 | return noit_false; |
|---|
| 827 | 843 | if(!ctx->res.output) |
|---|
| 828 | | assert(ctx->res.output = bchain_alloc(DEFAULT_BCHAINSIZE)); |
|---|
| | 844 | assert(ctx->res.output = ALLOC_BCHAIN(DEFAULT_BCHAINSIZE)); |
|---|
| 829 | 845 | o = ctx->res.output; |
|---|
| 830 | 846 | while(o->next) o = o->next; |
|---|
| … | … | |
| 832 | 848 | if(o->allocd == o->start + o->size) { |
|---|
| 833 | 849 | /* Filled up, need another */ |
|---|
| 834 | | o->next = bchain_alloc(DEFAULT_BCHAINSIZE); |
|---|
| | 850 | o->next = ALLOC_BCHAIN(DEFAULT_BCHAINSIZE); |
|---|
| 835 | 851 | o->next->prev = o->next; |
|---|
| 836 | 852 | o = o->next; |
|---|
| … | … | |
| 874 | 890 | |
|---|
| 875 | 891 | assert(!ctx->res.leader); |
|---|
| 876 | | ctx->res.leader = b = bchain_alloc(DEFAULT_BCHAINSIZE); |
|---|
| | 892 | ctx->res.leader = b = ALLOC_BCHAIN(DEFAULT_BCHAINSIZE); |
|---|
| 877 | 893 | |
|---|
| 878 | 894 | protocol_str = ctx->res.protocol == NOIT_HTTP11 ? |
|---|
| … | … | |
| 888 | 904 | #define CTX_LEADER_APPEND(s, slen) do { \ |
|---|
| 889 | 905 | if(b->size + slen > DEFAULT_BCHAINSIZE) { \ |
|---|
| 890 | | b->next = bchain_alloc(DEFAULT_BCHAINSIZE); \ |
|---|
| | 906 | b->next = ALLOC_BCHAIN(DEFAULT_BCHAINSIZE); \ |
|---|
| 891 | 907 | assert(b->next); \ |
|---|
| 892 | 908 | b->next->prev = b; \ |
|---|
| … | … | |
| 984 | 1000 | if(hexlen == 0) hexlen = 1; |
|---|
| 985 | 1001 | |
|---|
| 986 | | out = bchain_alloc(hexlen + 4 + maxlen); |
|---|
| | 1002 | out = ALLOC_BCHAIN(hexlen + 4 + maxlen); |
|---|
| 987 | 1003 | /* if we're chunked, let's give outselved hexlen + 2 prefix space */ |
|---|
| 988 | 1004 | if(opts & NOIT_HTTP_CHUNKED) out->start = hexlen + 2; |
|---|
| … | … | |
| 1050 | 1066 | r = ctx->res.output_raw = n; |
|---|
| 1051 | 1067 | } |
|---|
| 1052 | | tofree = o; o = o->next; free(tofree); /* advance and free */ |
|---|
| | 1068 | tofree = o; o = o->next; FREE_BCHAIN(tofree); /* advance and free */ |
|---|
| 1053 | 1069 | } |
|---|
| 1054 | 1070 | ctx->res.output = NULL; |
|---|
| rd5e874f |
rfa84adf |
|
| 67 | 67 | #define BCHAIN_SPACE(a) ((a)->allocd - (a)->size - (a)->start) |
|---|
| 68 | 68 | |
|---|
| 69 | | API_EXPORT(struct bchain *) bchain_alloc(size_t size); |
|---|
| 70 | | API_EXPORT(void) bchain_free(struct bchain *); |
|---|
| 71 | | |
|---|
| 72 | 69 | typedef struct { |
|---|
| 73 | 70 | eventer_t e; |
|---|
| … | … | |
| 131 | 128 | noit_http_dispatch_func dispatcher; |
|---|
| 132 | 129 | void *dispatcher_closure; |
|---|
| 133 | | eventer_func_t drive; |
|---|
| 134 | 130 | acceptor_closure_t *ac; |
|---|
| 135 | 131 | } noit_http_session_ctx; |
|---|
| … | … | |
| 140 | 136 | API_EXPORT(void) |
|---|
| 141 | 137 | noit_http_session_ctx_release(noit_http_session_ctx *); |
|---|
| | 138 | |
|---|
| | 139 | API_EXPORT(void) |
|---|
| | 140 | noit_http_ctx_acceptor_free(void *); /* just calls noit_http_session_ctx_release */ |
|---|
| | 141 | |
|---|
| 142 | 142 | API_EXPORT(void) |
|---|
| 143 | 143 | noit_http_process_querystring(noit_http_request *); |
|---|
| 144 | 144 | |
|---|
| 145 | 145 | API_EXPORT(int) |
|---|
| 146 | | noit_http_session_drive(eventer_t, int, void *, struct timeval *); |
|---|
| | 146 | noit_http_session_drive(eventer_t, int, void *, struct timeval *, int *done); |
|---|
| 147 | 147 | |
|---|
| 148 | 148 | API_EXPORT(noit_boolean) |
|---|
| r37f5a09 |
rfa84adf |
|
| 56 | 56 | acceptor_closure_free(acceptor_closure_t *ac) { |
|---|
| 57 | 57 | if(ac->remote_cn) free(ac->remote_cn); |
|---|
| | 58 | if(ac->service_ctx_free && ac->service_ctx) |
|---|
| | 59 | ac->service_ctx_free(ac->service_ctx); |
|---|
| 58 | 60 | free(ac); |
|---|
| 59 | 61 | } |
|---|
| r37f5a09 |
rfa84adf |
|
| 56 | 56 | eventer_func_t dispatch; |
|---|
| 57 | 57 | u_int32_t cmd; |
|---|
| | 58 | void (*service_ctx_free)(void *); |
|---|
| 58 | 59 | } acceptor_closure_t; |
|---|
| 59 | 60 | |
|---|
| r4778e9c |
rfa84adf |
|
| 273 | 273 | } |
|---|
| 274 | 274 | void |
|---|
| 275 | | noit_http_rest_closure_free(noit_http_rest_closure_t *restc) { |
|---|
| | 275 | noit_http_rest_closure_free(void *v) { |
|---|
| | 276 | noit_http_rest_closure_t *restc = v; |
|---|
| 276 | 277 | free(restc->remote_cn); |
|---|
| 277 | 278 | noit_http_rest_clean_request(restc); |
|---|
| … | … | |
| 300 | 301 | noit_http_rest_handler(eventer_t e, int mask, void *closure, |
|---|
| 301 | 302 | struct timeval *now) { |
|---|
| 302 | | int newmask = EVENTER_READ | EVENTER_EXCEPTION; |
|---|
| | 303 | int newmask = EVENTER_READ | EVENTER_EXCEPTION, rv, done = 0; |
|---|
| 303 | 304 | acceptor_closure_t *ac = closure; |
|---|
| 304 | 305 | noit_http_rest_closure_t *restc = ac->service_ctx; |
|---|
| … | … | |
| 309 | 310 | eventer_remove_fd(e->fd); |
|---|
| 310 | 311 | e->opset->close(e->fd, &newmask, e); |
|---|
| 311 | | if(restc) noit_http_rest_closure_free(restc); |
|---|
| 312 | 312 | if(ac) acceptor_closure_free(ac); |
|---|
| 313 | 313 | return 0; |
|---|
| … | … | |
| 317 | 317 | const char *primer = ""; |
|---|
| 318 | 318 | ac->service_ctx = restc = noit_http_rest_closure_alloc(); |
|---|
| | 319 | ac->service_ctx_free = noit_http_rest_closure_free; |
|---|
| 319 | 320 | restc->ac = ac; |
|---|
| 320 | 321 | restc->remote_cn = strdup(ac->remote_cn ? ac->remote_cn : ""); |
|---|
| … | … | |
| 347 | 348 | noit_http_session_prime_input(restc->http_ctx, primer, 4); |
|---|
| 348 | 349 | } |
|---|
| 349 | | return restc->http_ctx->drive(e, mask, restc->http_ctx, now); |
|---|
| | 350 | rv = noit_http_session_drive(e, mask, restc->http_ctx, now, &done); |
|---|
| | 351 | if(done) { |
|---|
| | 352 | if(ac) acceptor_closure_free(ac); |
|---|
| | 353 | } |
|---|
| | 354 | return rv; |
|---|
| 350 | 355 | } |
|---|
| 351 | 356 | |
|---|
| … | … | |
| 353 | 358 | noit_http_rest_raw_handler(eventer_t e, int mask, void *closure, |
|---|
| 354 | 359 | struct timeval *now) { |
|---|
| 355 | | int newmask = EVENTER_READ | EVENTER_EXCEPTION; |
|---|
| | 360 | int newmask = EVENTER_READ | EVENTER_EXCEPTION, rv, done = 0; |
|---|
| 356 | 361 | acceptor_closure_t *ac = closure; |
|---|
| 357 | 362 | noit_http_rest_closure_t *restc = ac->service_ctx; |
|---|
| … | … | |
| 361 | 366 | eventer_remove_fd(e->fd); |
|---|
| 362 | 367 | e->opset->close(e->fd, &newmask, e); |
|---|
| 363 | | if(restc) noit_http_rest_closure_free(restc); |
|---|
| 364 | 368 | if(ac) acceptor_closure_free(ac); |
|---|
| 365 | 369 | return 0; |
|---|
| … | … | |
| 367 | 371 | if(!ac->service_ctx) { |
|---|
| 368 | 372 | ac->service_ctx = restc = noit_http_rest_closure_alloc(); |
|---|
| | 373 | ac->service_ctx_free = noit_http_rest_closure_free; |
|---|
| 369 | 374 | restc->ac = ac; |
|---|
| 370 | 375 | restc->http_ctx = |
|---|
| … | … | |
| 372 | 377 | restc, e, ac); |
|---|
| 373 | 378 | } |
|---|
| 374 | | return restc->http_ctx->drive(e, mask, restc->http_ctx, now); |
|---|
| | 379 | rv = noit_http_session_drive(e, mask, restc->http_ctx, now, &done); |
|---|
| | 380 | if(done) { |
|---|
| | 381 | if(ac) acceptor_closure_free(ac); |
|---|
| | 382 | } |
|---|
| | 383 | return rv; |
|---|
| 375 | 384 | } |
|---|
| 376 | 385 | |
|---|
| r4778e9c |
rfa84adf |
|
| 86 | 86 | int *mask, int *complete) ; |
|---|
| 87 | 87 | |
|---|
| 88 | | API_EXPORT(void) |
|---|
| 89 | | noit_http_rest_closure_free(noit_http_rest_closure_t *restc); |
|---|
| 90 | | |
|---|
| 91 | 88 | API_EXPORT(int) |
|---|
| 92 | 89 | noit_rest_simple_file_handler(noit_http_rest_closure_t *restc, |
|---|
| r76fe6db |
rfa84adf |
|
| 498 | 498 | stratcon_realtime_http_handler(eventer_t e, int mask, void *closure, |
|---|
| 499 | 499 | struct timeval *now) { |
|---|
| | 500 | int done = 0, rv; |
|---|
| 500 | 501 | acceptor_closure_t *ac = closure; |
|---|
| 501 | 502 | noit_http_session_ctx *http_ctx = ac->service_ctx; |
|---|
| 502 | | return http_ctx->drive(e, mask, http_ctx, now); |
|---|
| | 503 | rv = noit_http_session_drive(e, mask, http_ctx, now, &done); |
|---|
| | 504 | if(done) acceptor_closure_free(ac); |
|---|
| | 505 | return rv; |
|---|
| 503 | 506 | } |
|---|
| 504 | 507 | static int |
|---|
| … | … | |
| 508 | 511 | const char *document_domain = NULL; |
|---|
| 509 | 512 | noit_http_session_ctx *ctx = restc->http_ctx; |
|---|
| | 513 | acceptor_closure_t *ac = restc->ac; |
|---|
| 510 | 514 | |
|---|
| 511 | 515 | /* Rewire the handler */ |
|---|
| 512 | | restc->ac->service_ctx = ctx; |
|---|
| 513 | | |
|---|
| 514 | | if(!noit_hash_retr_str(restc->ac->config, |
|---|
| | 516 | if(ac->service_ctx_free) |
|---|
| | 517 | ac->service_ctx_free(ac->service_ctx); |
|---|
| | 518 | ac->service_ctx = ctx; |
|---|
| | 519 | ac->service_ctx_free = noit_http_ctx_acceptor_free; |
|---|
| | 520 | |
|---|
| | 521 | if(!noit_hash_retr_str(ac->config, |
|---|
| 515 | 522 | "document_domain", strlen("document_domain"), |
|---|
| 516 | 523 | &document_domain)) { |
|---|
| … | … | |
| 518 | 525 | document_domain = ""; |
|---|
| 519 | 526 | } |
|---|
| 520 | | noit_http_rest_closure_free(restc); |
|---|
| 521 | 527 | |
|---|
| 522 | 528 | noit_http_process_querystring(&ctx->req); |
|---|
| … | … | |
| 525 | 531 | ctx->dispatcher = stratcon_request_dispatcher; |
|---|
| 526 | 532 | ctx->dispatcher_closure = alloc_realtime_context(document_domain); |
|---|
| 527 | | //ctx->drive = stratcon_realtime_http_handler; |
|---|
| 528 | 533 | return stratcon_request_dispatcher(ctx); |
|---|
| 529 | 534 | } |
|---|