Changeset fa84adfbc712fa0e327aa3ba60ccb09632d36fb0

Show
Ignore:
Timestamp:
05/22/10 18:29:54 (5 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
  • src/noit_http.c

    r30339cd rfa84adf  
    7777} 
    7878 
    79 struct bchain *bchain_alloc(size_t size) { 
     79struct bchain *bchain_alloc(size_t size, int line) { 
    8080  struct bchain *n; 
    8181  n = malloc(size + ((char *)n->buff - (char *)n)); 
     82  /*noitL(noit_error, "bchain_alloc(%p) : %d\n", n, line);*/ 
    8283  if(!n) return NULL; 
    8384  n->prev = n->next = NULL; 
     
    8687  return n; 
    8788} 
     89void 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__) 
    8895#define RELEASE_BCHAIN(a) do { \ 
    8996  while(a) { \ 
     
    9198    __b = a; \ 
    9299    a = __b->next; \ 
    93     bchain_free(__b); \ 
     100    bchain_free(__b, __LINE__); \ 
    94101  } \ 
    95102} while(0) 
    96103struct bchain *bchain_from_data(const void *d, size_t size) { 
    97104  struct bchain *n; 
    98   n = bchain_alloc(size); 
     105  n = ALLOC_BCHAIN(size); 
    99106  if(!n) return NULL; 
    100107  memcpy(n->buff, d, size); 
    101108  n->size = size; 
    102109  return n; 
    103 } 
    104 void bchain_free(struct bchain *b) { 
    105   free(b); 
    106110} 
    107111 
     
    165169    new_size = end_in_f + (b->start + b->size - start_in_b); 
    166170    if(new_size > DEFAULT_BCHAINSIZE) return noit_false; /* string too long */ 
    167     f = bchain_alloc(new_size); 
     171    f = ALLOC_BCHAIN(new_size); 
    168172    f->prev = b; 
    169173    f->next = b->next; 
     
    246250  if(ctx->res.output_raw_offset >= b->size) { 
    247251    *head = b->next; 
    248     bchain_free(b); 
     252    FREE_BCHAIN(b); 
    249253    b = *head; 
    250254    if(b) b->prev = NULL; 
     
    327331    int lsize = req->current_input->size - req->current_offset; 
    328332    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); 
    330334    req->first_input->prev = NULL; 
    331335    req->first_input->next = req->current_input->next; 
     
    339343      req->last_input = req->first_input; 
    340344    else 
    341       bchain_free(req->current_input); 
     345      FREE_BCHAIN(req->current_input); 
    342346  } 
    343347  else { 
     
    404408          l1 = strlen(prefix); 
    405409          l2 = strlen(value); 
    406           b = bchain_alloc(l1 + l2 + 2); 
     410          b = ALLOC_BCHAIN(l1 + l2 + 2); 
    407411          b->next = req->current_request_chain; 
    408412          b->next->prev = b; 
     
    511515    if(!in) { 
    512516      in = ctx->req.first_input = ctx->req.last_input = 
    513         bchain_alloc(DEFAULT_BCHAINSIZE); 
     517        ALLOC_BCHAIN(DEFAULT_BCHAINSIZE); 
    514518      if(!in) goto full_error; 
    515519    } 
     
    518522       DEFAULT_BCHAINMINREAD < DEFAULT_BCHAINSIZE) { /* and we can */ 
    519523      in->next = ctx->req.last_input = 
    520         bchain_alloc(DEFAULT_BCHAINSIZE); 
     524        ALLOC_BCHAIN(DEFAULT_BCHAINSIZE); 
    521525      in->next->prev = in; 
    522526      in = in->next; 
     
    556560  if(len > DEFAULT_BCHAINSIZE) return noit_false; 
    557561  ctx->req.first_input = ctx->req.last_input = 
    558       bchain_alloc(DEFAULT_BCHAINSIZE); 
     562      ALLOC_BCHAIN(DEFAULT_BCHAINSIZE); 
    559563  memcpy(ctx->req.first_input->buff, data, len); 
    560564  ctx->req.first_input->size = len; 
     
    576580  RELEASE_BCHAIN(ctx->req.current_request_chain); 
    577581  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)); 
    579584} 
    580585void 
     
    591596  if(noit_atomic_dec32(&ctx->ref_cnt) == 0) { 
    592597    noit_http_request_release(ctx); 
     598    if(ctx->req.first_input) RELEASE_BCHAIN(ctx->req.first_input); 
    593599    noit_http_response_release(ctx); 
    594600    free(ctx); 
    595601  } 
     602} 
     603void 
     604noit_http_ctx_acceptor_free(void *v) { 
     605  noit_http_ctx_session_release((noit_http_session_ctx *)v); 
    596606} 
    597607int 
     
    636646      if(!in) 
    637647        in = ctx->req.first_input = ctx->req.last_input = 
    638             bchain_alloc(DEFAULT_BCHAINSIZE); 
     648            ALLOC_BCHAIN(DEFAULT_BCHAINSIZE); 
    639649      else if(in->start + in->size >= in->allocd) { 
    640         in->next = bchain_alloc(DEFAULT_BCHAINSIZE); 
     650        in->next = ALLOC_BCHAIN(DEFAULT_BCHAINSIZE); 
    641651        in = ctx->req.last_input = in->next; 
    642652      } 
     
    670680int 
    671681noit_http_session_drive(eventer_t e, int origmask, void *closure, 
    672                         struct timeval *now) { 
     682                        struct timeval *now, int *done) { 
    673683  noit_http_session_ctx *ctx = closure; 
    674684  int rv = 0; 
     
    726736   abort_drive: 
    727737    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    } 
    730742    goto release; 
    731743  } 
     
    741753  } 
    742754  noitL(http_debug, " <- noit_http_session_drive(%d) [%x]\n", e->fd, 0); 
    743   return 0; 
     755  goto abort_drive; 
     756 
    744757 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; 
    745762  noit_http_ctx_session_release(ctx); 
    746763  noitL(http_debug, " <- noit_http_session_drive(%d) [%x]\n", e->fd, 0); 
     
    758775  ctx->dispatcher = f; 
    759776  ctx->dispatcher_closure = c; 
    760   ctx->drive = noit_http_session_drive; 
    761777  ctx->ac = ac; 
    762778  return ctx; 
     
    826842    return noit_false; 
    827843  if(!ctx->res.output) 
    828     assert(ctx->res.output = bchain_alloc(DEFAULT_BCHAINSIZE)); 
     844    assert(ctx->res.output = ALLOC_BCHAIN(DEFAULT_BCHAINSIZE)); 
    829845  o = ctx->res.output; 
    830846  while(o->next) o = o->next; 
     
    832848    if(o->allocd == o->start + o->size) { 
    833849      /* Filled up, need another */ 
    834       o->next = bchain_alloc(DEFAULT_BCHAINSIZE); 
     850      o->next = ALLOC_BCHAIN(DEFAULT_BCHAINSIZE); 
    835851      o->next->prev = o->next; 
    836852      o = o->next; 
     
    874890 
    875891  assert(!ctx->res.leader); 
    876   ctx->res.leader = b = bchain_alloc(DEFAULT_BCHAINSIZE); 
     892  ctx->res.leader = b = ALLOC_BCHAIN(DEFAULT_BCHAINSIZE); 
    877893 
    878894  protocol_str = ctx->res.protocol == NOIT_HTTP11 ? 
     
    888904#define CTX_LEADER_APPEND(s, slen) do { \ 
    889905  if(b->size + slen > DEFAULT_BCHAINSIZE) { \ 
    890     b->next = bchain_alloc(DEFAULT_BCHAINSIZE); \ 
     906    b->next = ALLOC_BCHAIN(DEFAULT_BCHAINSIZE); \ 
    891907    assert(b->next); \ 
    892908    b->next->prev = b; \ 
     
    9841000  if(hexlen == 0) hexlen = 1; 
    9851001 
    986   out = bchain_alloc(hexlen + 4 + maxlen); 
     1002  out = ALLOC_BCHAIN(hexlen + 4 + maxlen); 
    9871003  /* if we're chunked, let's give outselved hexlen + 2 prefix space */ 
    9881004  if(opts & NOIT_HTTP_CHUNKED) out->start = hexlen + 2; 
     
    10501066      r = ctx->res.output_raw = n; 
    10511067    } 
    1052     tofree = o; o = o->next; free(tofree); /* advance and free */ 
     1068    tofree = o; o = o->next; FREE_BCHAIN(tofree); /* advance and free */ 
    10531069  } 
    10541070  ctx->res.output = NULL; 
  • src/noit_http.h

    rd5e874f rfa84adf  
    6767#define BCHAIN_SPACE(a) ((a)->allocd - (a)->size - (a)->start) 
    6868 
    69 API_EXPORT(struct bchain *) bchain_alloc(size_t size); 
    70 API_EXPORT(void) bchain_free(struct bchain *); 
    71  
    7269typedef struct { 
    7370  eventer_t e; 
     
    131128  noit_http_dispatch_func dispatcher; 
    132129  void *dispatcher_closure; 
    133   eventer_func_t drive; 
    134130  acceptor_closure_t *ac; 
    135131} noit_http_session_ctx; 
     
    140136API_EXPORT(void) 
    141137  noit_http_session_ctx_release(noit_http_session_ctx *); 
     138 
     139API_EXPORT(void) 
     140  noit_http_ctx_acceptor_free(void *); /* just calls noit_http_session_ctx_release */ 
     141 
    142142API_EXPORT(void) 
    143143  noit_http_process_querystring(noit_http_request *); 
    144144 
    145145API_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); 
    147147 
    148148API_EXPORT(noit_boolean) 
  • src/noit_listener.c

    r37f5a09 rfa84adf  
    5656acceptor_closure_free(acceptor_closure_t *ac) { 
    5757  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); 
    5860  free(ac); 
    5961} 
  • src/noit_listener.h

    r37f5a09 rfa84adf  
    5656  eventer_func_t dispatch; 
    5757  u_int32_t cmd; 
     58  void (*service_ctx_free)(void *); 
    5859} acceptor_closure_t; 
    5960 
  • src/noit_rest.c

    r4778e9c rfa84adf  
    273273} 
    274274void 
    275 noit_http_rest_closure_free(noit_http_rest_closure_t *restc) { 
     275noit_http_rest_closure_free(void *v) { 
     276  noit_http_rest_closure_t *restc = v; 
    276277  free(restc->remote_cn); 
    277278  noit_http_rest_clean_request(restc); 
     
    300301noit_http_rest_handler(eventer_t e, int mask, void *closure, 
    301302                       struct timeval *now) { 
    302   int newmask = EVENTER_READ | EVENTER_EXCEPTION
     303  int newmask = EVENTER_READ | EVENTER_EXCEPTION, rv, done = 0
    303304  acceptor_closure_t *ac = closure; 
    304305  noit_http_rest_closure_t *restc = ac->service_ctx; 
     
    309310    eventer_remove_fd(e->fd); 
    310311    e->opset->close(e->fd, &newmask, e); 
    311     if(restc) noit_http_rest_closure_free(restc); 
    312312    if(ac) acceptor_closure_free(ac); 
    313313    return 0; 
     
    317317    const char *primer = ""; 
    318318    ac->service_ctx = restc = noit_http_rest_closure_alloc(); 
     319    ac->service_ctx_free = noit_http_rest_closure_free; 
    319320    restc->ac = ac; 
    320321    restc->remote_cn = strdup(ac->remote_cn ? ac->remote_cn : ""); 
     
    347348    noit_http_session_prime_input(restc->http_ctx, primer, 4); 
    348349  } 
    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; 
    350355} 
    351356 
     
    353358noit_http_rest_raw_handler(eventer_t e, int mask, void *closure, 
    354359                           struct timeval *now) { 
    355   int newmask = EVENTER_READ | EVENTER_EXCEPTION
     360  int newmask = EVENTER_READ | EVENTER_EXCEPTION, rv, done = 0
    356361  acceptor_closure_t *ac = closure; 
    357362  noit_http_rest_closure_t *restc = ac->service_ctx; 
     
    361366    eventer_remove_fd(e->fd); 
    362367    e->opset->close(e->fd, &newmask, e); 
    363     if(restc) noit_http_rest_closure_free(restc); 
    364368    if(ac) acceptor_closure_free(ac); 
    365369    return 0; 
     
    367371  if(!ac->service_ctx) { 
    368372    ac->service_ctx = restc = noit_http_rest_closure_alloc(); 
     373    ac->service_ctx_free = noit_http_rest_closure_free; 
    369374    restc->ac = ac; 
    370375    restc->http_ctx = 
     
    372377                                  restc, e, ac); 
    373378  } 
    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; 
    375384} 
    376385 
  • src/noit_rest.h

    r4778e9c rfa84adf  
    8686                      int *mask, int *complete) ; 
    8787 
    88 API_EXPORT(void) 
    89   noit_http_rest_closure_free(noit_http_rest_closure_t *restc); 
    90  
    9188API_EXPORT(int) 
    9289  noit_rest_simple_file_handler(noit_http_rest_closure_t *restc, 
  • src/stratcon_realtime_http.c

    r76fe6db rfa84adf  
    498498stratcon_realtime_http_handler(eventer_t e, int mask, void *closure, 
    499499                               struct timeval *now) { 
     500  int done = 0, rv; 
    500501  acceptor_closure_t *ac = closure; 
    501502  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; 
    503506} 
    504507static int 
     
    508511  const char *document_domain = NULL; 
    509512  noit_http_session_ctx *ctx = restc->http_ctx; 
     513  acceptor_closure_t *ac = restc->ac; 
    510514 
    511515  /* 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, 
    515522                         "document_domain", strlen("document_domain"), 
    516523                         &document_domain)) { 
     
    518525    document_domain = ""; 
    519526  } 
    520   noit_http_rest_closure_free(restc); 
    521527 
    522528  noit_http_process_querystring(&ctx->req); 
     
    525531  ctx->dispatcher = stratcon_request_dispatcher; 
    526532  ctx->dispatcher_closure = alloc_realtime_context(document_domain); 
    527   //ctx->drive = stratcon_realtime_http_handler; 
    528533  return stratcon_request_dispatcher(ctx); 
    529534}