Changeset 483ffbb2a71b31651cb48c74c7436508890169f4

Show
Ignore:
Timestamp:
06/05/08 03:10:39 (7 years ago)
Author:
Theo Schlossnagle <jesus@omniti.com>
git-committer:
Theo Schlossnagle <jesus@omniti.com> 1212635439 +0000
git-parent:

[f920aec8f7779dc67b4ea347d8da0384b27627b4]

git-author:
Theo Schlossnagle <jesus@omniti.com> 1212635439 +0000
Message:

implement write and fix up read... luaL_Buffer is crap -- avoid it. show our accomplishment with a short, simple Varnish stat query check, refs #28

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/modules/lua.c

    rdb9f2be r483ffbb  
    460460  check->flags &= ~NP_RUNNING; 
    461461 
     462  lua_getglobal(ci->lmc->lua_state, "noit_coros"); 
     463  luaL_unref(ci->lmc->lua_state, -1, ci->coro_state_ref); 
     464  lua_pop(ci->lmc->lua_state, 2); 
     465 
    462466 done: 
    463467  lua_gc(ci->lmc->lua_state, LUA_GCCOLLECT, 0); 
  • src/modules/lua_noit.c

    r1431d99 r483ffbb  
    2222 
    2323struct nl_slcl { 
     24  int send_size; 
    2425  struct timeval start; 
    25   luaL_Buffer inbuff; 
    26   int read_sofar; 
    27   int read_goal; 
     26  char *inbuff; 
     27  int   inbuff_allocd; 
     28  int   inbuff_len; 
     29  size_t read_sofar; 
     30  size_t read_goal; 
    2831  const char *read_terminator; 
    2932  const char *outbuff; 
    30   int write_sofar; 
    31   int write_goal; 
     33  size_t write_sofar; 
     34  size_t write_goal; 
    3235  eventer_t *eptr; 
    3336  lua_State *L; 
    3437}; 
     38 
     39static void 
     40inbuff_addlstring(struct nl_slcl *cl, const char *b, int l) { 
     41  int newsize = 0; 
     42  char *newbuf; 
     43  if(cl->inbuff_len + l > cl->inbuff_allocd) 
     44    newsize = cl->inbuff_len + l; 
     45  if(newsize) { 
     46    newbuf = cl->inbuff_allocd ? realloc(cl->inbuff, newsize) : malloc(newsize); 
     47    assert(newbuf); 
     48    cl->inbuff = newbuf; 
     49    cl->inbuff_allocd = newsize; 
     50  } 
     51  memcpy(cl->inbuff + cl->inbuff_len, b, l); 
     52  cl->inbuff_len += l; 
     53} 
    3554 
    3655static int 
     
    147166      int remaining = cl->read_goal - cl->read_sofar; 
    148167      /* copy up to the goal into the inbuff */ 
    149       luaL_addlstring(&cl->inbuff, buff, MIN(len, remaining)); 
     168      inbuff_addlstring(cl, buff, MIN(len, remaining)); 
    150169      cl->read_sofar += len; 
    151170      if(cl->read_sofar >= cl->read_goal) { /* We're done */ 
    152         luaL_pushresult(&cl->inbuff); 
     171        lua_pushlstring(cl->L, cl->inbuff, cl->read_goal); 
     172        args = 1; 
    153173        cl->read_sofar -= cl->read_goal; 
    154         if(cl->read_sofar > 0) { /* We have to buffer this for next read */ 
    155           luaL_buffinit(cl->L, &cl->inbuff); 
    156           luaL_addlstring(&cl->inbuff, 
    157                           buff + remaining, 
    158                           cl->read_sofar); 
     174        if(cl->read_sofar > 0) {  /* We have to buffer this for next read */ 
     175          cl->inbuff_len = 0; 
     176          inbuff_addlstring(cl, buff + remaining, cl->read_sofar); 
    159177        } 
    160         args = 1; 
    161178        break; 
    162179      } 
     
    167184      cp = strnstr(buff, cl->read_terminator, len); 
    168185      if(cp) remaining = cp - buff + strlen(cl->read_terminator); 
    169       luaL_addlstring(&cl->inbuff, buff, MIN(len, remaining)); 
     186      inbuff_addlstring(cl, buff, MIN(len, remaining)); 
    170187      cl->read_sofar += len; 
    171188      if(cp) { 
    172         luaL_pushresult(&cl->inbuff); 
     189        lua_pushlstring(cl->L, cl->inbuff, cl->inbuff_len); 
     190        args = 1; 
    173191        cl->read_sofar = len - remaining; 
    174192        if(cl->read_sofar > 0) { /* We have to buffer this for next read */ 
    175           luaL_buffinit(cl->L, &cl->inbuff)
    176           luaL_addlstring(&cl->inbuff, buff + remaining, cl->read_sofar); 
     193          cl->inbuff_len = 0
     194          inbuff_addlstring(cl, buff + remaining, cl->read_sofar); 
    177195        } 
    178         args = 1; 
    179196        break; 
    180197      } 
     
    185202  } 
    186203  else if(len == -1 && errno == EAGAIN) { 
    187     return EVENTER_READ | EVENTER_EXCEPTION; 
     204    return mask | EVENTER_EXCEPTION; 
    188205  } 
    189206  else { 
     
    212229  e = *eptr; 
    213230  cl = e->closure; 
    214   if(cl->read_sofar == 0) luaL_buffinit(L, &cl->inbuff); 
    215231  cl->read_goal = 0; 
    216232  cl->read_terminator = NULL; 
    217   fprintf(stderr, "initiating read... (%d bytes buffered)\n", cl->read_sofar); 
    218233 
    219234  if(lua_isnumber(L, 1)) { 
    220235    cl->read_goal = lua_tointeger(L, 1); 
    221     fprintf(stderr, " read wants %d bytes\n", cl->read_goal); 
    222236    if(cl->read_goal <= cl->read_sofar) { 
    223       const char *current_buff; 
    224237      int base; 
    225       size_t len; 
    226238     i_know_better: 
    227239      base = lua_gettop(L); 
    228240      /* We have enough, we can service this right here */ 
    229       luaL_pushresult(&cl->inbuff); 
    230       current_buff = lua_tolstring(L, base + 1, &len); 
    231       assert(len == cl->read_sofar); 
    232       lua_pop(L, 1); 
    233       lua_pushlstring(L, current_buff, cl->read_goal); 
     241      lua_pushlstring(L, cl->inbuff, cl->read_goal); 
    234242      cl->read_sofar -= cl->read_goal; 
    235243      if(cl->read_sofar) { 
    236         luaL_buffinit(L, &cl->inbuff); 
    237         luaL_addlstring(&cl->inbuff, current_buff + cl->read_goal, 
    238                         cl->read_sofar); 
     244        memmove(cl->inbuff, cl->inbuff + cl->read_goal, cl->read_sofar); 
     245        cl->inbuff_len = cl->read_sofar; 
    239246      } 
    240247      return 1; 
     
    243250  else { 
    244251    cl->read_terminator = lua_tostring(L, 1); 
    245     fprintf(stderr, " read wants up to [%s]\n", cl->read_terminator); 
    246252    if(cl->read_sofar) { 
    247253      const char *cp; 
    248254      /* Ugh... inernalism */ 
    249       cp = strnstr(cl->inbuff.buffer, cl->read_terminator, cl->read_sofar); 
     255      cp = strnstr(cl->inbuff, cl->read_terminator, cl->read_sofar); 
    250256      if(cp) { 
    251257        /* Here we matched... and we _know_ that someone actually wants: 
     
    253259         * give it to them. 
    254260         */ 
    255         cl->read_goal = strlen(cl->read_terminator) + cp - cl->inbuff.buffer
     261        cl->read_goal = strlen(cl->read_terminator) + cp - cl->inbuff
    256262        cl->read_terminator = NULL; 
    257263        assert(cl->read_goal <= cl->read_sofar); 
     
    265271  eventer_add(e); 
    266272  return noit_lua_yield(ci, 0); 
     273} 
     274static int 
     275noit_lua_socket_write_complete(eventer_t e, int mask, void *vcl, 
     276                               struct timeval *now) { 
     277  noit_lua_check_info_t *ci; 
     278  struct nl_slcl *cl = vcl; 
     279  int rv; 
     280  int args = 0; 
     281 
     282  ci = get_ci(cl->L); 
     283  assert(ci); 
     284 
     285  if(mask & EVENTER_EXCEPTION) { 
     286    lua_pushinteger(cl->L, -1); 
     287    args = 1; 
     288    goto alldone; 
     289  } 
     290  while((rv = e->opset->write(e->fd, 
     291                              cl->outbuff + cl->write_sofar, 
     292                              MIN(cl->send_size, cl->write_goal), 
     293                              &mask, e)) > 0) { 
     294    cl->write_sofar += rv; 
     295    assert(cl->write_sofar <= cl->write_goal); 
     296    if(cl->write_sofar == cl->write_goal) break; 
     297  } 
     298  if(rv > 0) { 
     299    lua_pushinteger(cl->L, cl->write_goal); 
     300    args = 1; 
     301  } 
     302  else if(rv == -1 && errno == EAGAIN) { 
     303    return mask | EVENTER_EXCEPTION; 
     304  } 
     305  else { 
     306    lua_pushinteger(cl->L, -1); 
     307    args = 1; 
     308    if(rv == -1) { 
     309      lua_pushstring(cl->L, strerror(errno)); 
     310      args++; 
     311    } 
     312  } 
     313 
     314 alldone: 
     315  noit_lua_check_deregister_event(ci, e, 0); 
     316  *(cl->eptr) = eventer_alloc(); 
     317  memcpy(*cl->eptr, e, sizeof(*e)); 
     318  noit_lua_check_register_event(ci, *cl->eptr); 
     319  noit_lua_resume(ci, args); 
     320  return 0; 
     321} 
     322static int 
     323noit_lua_socket_write(lua_State *L) { 
     324  int rv, mask; 
     325  struct nl_slcl *cl; 
     326  noit_lua_check_info_t *ci; 
     327  eventer_t e, *eptr; 
     328 
     329  ci = get_ci(L); 
     330  assert(ci); 
     331 
     332  eptr = lua_touserdata(L, lua_upvalueindex(1)); 
     333  e = *eptr; 
     334  cl = e->closure; 
     335  cl->write_sofar = 0; 
     336  cl->outbuff = lua_tolstring(L, 1, &cl->write_goal); 
     337 
     338  while((rv = e->opset->write(e->fd, 
     339                              cl->outbuff + cl->write_sofar, 
     340                              MIN(cl->send_size, cl->write_goal), 
     341                              &mask, e)) > 0) { 
     342    cl->write_sofar += rv; 
     343    assert(cl->write_sofar <= cl->write_goal); 
     344    if(cl->write_sofar == cl->write_goal) break; 
     345  } 
     346  if(rv > 0) { 
     347    lua_pushinteger(L, cl->write_goal); 
     348    return 1; 
     349  } 
     350  if(rv == -1 && errno == EAGAIN) { 
     351    e->callback = noit_lua_socket_write_complete; 
     352    e->mask = mask | EVENTER_EXCEPTION; 
     353    eventer_add(e); 
     354    return noit_lua_yield(ci, 0); 
     355  } 
     356  lua_pushinteger(L, -1); 
     357  return 1; 
    267358} 
    268359static int 
     
    297388     } 
    298389     break; 
     390    case 'w': 
     391     if(!strcmp(k, "write")) { 
     392       lua_pushlightuserdata(L, udata); 
     393       lua_pushcclosure(L, noit_lua_socket_write, 1); 
     394       return 1; 
     395     } 
     396     break; 
    299397    default: 
    300398      break; 
     
    369467  struct nl_slcl *cl; 
    370468  noit_lua_check_info_t *ci; 
    371   socklen_t on
     469  socklen_t on, optlen
    372470  int fd; 
    373471  eventer_t e; 
     
    390488  cl = calloc(1, sizeof(*cl)); 
    391489  cl->L = L; 
     490 
     491  optlen = sizeof(cl->send_size); 
     492  if(getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &cl->send_size, &optlen) != 0) 
     493    cl->send_size = 4096; 
    392494 
    393495  e = eventer_alloc();