Changeset 618dd9f44bc6087b76e06e01b9d71dd16de7f1bd

Show
Ignore:
Timestamp:
07/02/12 20:25:12 (2 years ago)
Author:
Theo Schlossnagle <jesus@omniti.com>
git-committer:
Theo Schlossnagle <jesus@omniti.com> 1341260712 -0400
git-parent:

[87bd3acad6887327c872e2d7acdb1332fe5d471e]

git-author:
Theo Schlossnagle <jesus@omniti.com> 1341260712 -0400
Message:

add support for running lua outside of a check initiation. This might leak, it will need a lot of testing

Files:

Legend:

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

    rde52002 r618dd9f  
    8686noit_lua_check_info_t * 
    8787get_ci(lua_State *L) { 
     88  noit_lua_check_info_t *ci; 
     89  lua_module_closure_t *lmc; 
    8890  void *v = NULL; 
    8991  if(noit_hash_retrieve(&noit_coros, (const char *)&L, sizeof(L), &v)) 
    9092    return (noit_lua_check_info_t *)v; 
    91   return NULL; 
     93  ci = calloc(1, sizeof(*ci)); 
     94  ci->coro_state = L; 
     95  lua_getglobal(L, "noit_internal_lmc");; 
     96  ci->lmc = lua_touserdata(L, lua_gettop(L)); 
     97  lua_pop(L, 1); 
     98  noitL(noit_error, "lmc -> %p\n", ci->lmc); 
     99  noit_hash_store(&noit_coros, 
     100                  (const char *)&ci->coro_state, sizeof(ci->coro_state), 
     101                  ci); 
     102  return ci; 
    92103} 
    93104static void 
     
    696707    default: /* Errors */ 
    697708      noitL(nldeb, "lua resume returned: %d\n", result); 
     709      if(ci->current.status) free(ci->current.status); 
    698710      ci->current.status = strdup(ci->timed_out ? "timeout" : "unknown error"); 
    699711      ci->current.available = NP_UNAVAILABLE; 
     
    724736  check = ci->check; 
    725737  cancel_coro(ci); 
    726   noit_lua_log_results(self, check); 
    727   noit_lua_module_cleanup(self, check); 
    728   ci = NULL; /* we freed it... explode if someone uses it before we return */ 
    729   check->flags &= ~NP_RUNNING; 
     738  if(check) { 
     739    noitL(noit_error, "log results\n"); 
     740    noit_lua_log_results(self, check); 
     741    noit_lua_module_cleanup(self, check); 
     742    ci = NULL; /* we freed it... explode if someone uses it before we return */ 
     743    check->flags &= ~NP_RUNNING; 
     744  } 
    730745 
    731746 done: 
     
    848863  lua_module_closure_t *lmc; 
    849864  char *object; 
    850    
     865 
    851866  noitL(nldeb, "Loading lua module: %s\n", module_name); 
    852867  if(noit_conf_get_string(section, "@object", &object) == 0) { 
     
    863878  lmc = calloc(1, sizeof(*lmc)); 
    864879  lmc->object = object; 
     880  lmc->pending = calloc(1, sizeof(*lmc->pending)); 
    865881 
    866882  L = lmc->lua_state = lua_open(); 
     
    875891  lua_newtable(L); 
    876892  lua_setglobal(L, "noit_coros"); 
     893 
     894  lua_pushlightuserdata(L, lmc); 
     895  lua_setglobal(L, "noit_internal_lmc"); 
    877896 
    878897  lua_getfield(L, LUA_GLOBALSINDEX, "package"); 
  • src/modules/lua_noit.c

    r88ca598 r618dd9f  
    440440} 
    441441static int 
     442noit_lua_socket_bind(lua_State *L) { 
     443  noit_lua_check_info_t *ci; 
     444  eventer_t e, *eptr; 
     445  const char *target; 
     446  unsigned short port; 
     447  int8_t family; 
     448  int rv; 
     449  union { 
     450    struct sockaddr_in sin4; 
     451    struct sockaddr_in6 sin6; 
     452  } a; 
     453 
     454  ci = get_ci(L); 
     455  assert(ci); 
     456 
     457  eptr = lua_touserdata(L, lua_upvalueindex(1)); 
     458  if(eptr != lua_touserdata(L, 1)) 
     459    luaL_error(L, "must be called as method"); 
     460  e = *eptr; 
     461  target = lua_tostring(L, 2); 
     462  if(!target) target = ""; 
     463  port = lua_tointeger(L, 3); 
     464 
     465  family = AF_INET; 
     466  rv = inet_pton(family, target, &a.sin4.sin_addr); 
     467  if(rv != 1) { 
     468    family = AF_INET6; 
     469    rv = inet_pton(family, target, &a.sin6.sin6_addr); 
     470    if(rv != 1) { 
     471      memset(&a, 0, sizeof(a)); 
     472      lua_pushinteger(L, -1); 
     473      lua_pushfstring(L, "Cannot translate '%s' to IP\n", target); 
     474      return 2; 
     475    } 
     476    else { 
     477      /* We've IPv6 */ 
     478      a.sin6.sin6_family = AF_INET6; 
     479      a.sin6.sin6_port = htons(port); 
     480    } 
     481  } 
     482  else { 
     483    a.sin4.sin_family = family; 
     484    a.sin4.sin_port = htons(port); 
     485  } 
     486 
     487  rv = bind(e->fd, (struct sockaddr *)&a, 
     488            family==AF_INET ? sizeof(a.sin4) : sizeof(a.sin6)); 
     489  if(rv == 0) { 
     490    lua_pushinteger(L, 0); 
     491    return 1; 
     492  } 
     493  lua_pushinteger(L, -1); 
     494  lua_pushstring(L, strerror(errno)); 
     495  return 2; 
     496} 
     497static int 
    442498noit_lua_socket_connect(lua_State *L) { 
    443499  noit_lua_check_info_t *ci; 
     
    849905  k = lua_tostring(L, 2); 
    850906  switch(*k) { 
     907    case 'b': 
     908     LUA_DISPATCH(bind, noit_lua_socket_bind); 
     909     break; 
    851910    case 'c': 
    852911     LUA_DISPATCH(connect, noit_lua_socket_connect); 
     
    916975  return 0; 
    917976} 
     977 
     978static int 
     979nl_waitfor_notify(lua_State *L) { 
     980  noit_lua_check_info_t *ci; 
     981  struct nl_slcl *cl; 
     982  void *vptr; 
     983  const char *key; 
     984  int nargs; 
     985 
     986  ci = get_ci(L); 
     987  assert(ci); 
     988  nargs = lua_gettop(L); 
     989  if(nargs < 1) { 
     990    return 0; 
     991  } 
     992  key = lua_tostring(L, 1); 
     993  if(!noit_hash_retrieve(ci->lmc->pending, key, strlen(key), &vptr)) { 
     994    return 0; 
     995  } 
     996  noit_hash_delete(ci->lmc->pending, key, strlen(key), free, NULL); 
     997  cl = vptr; 
     998  lua_xmove(L, cl->L, nargs); 
     999 
     1000  ci = get_ci(cl->L); 
     1001  assert(ci); 
     1002  eventer_remove(cl->pending_event); 
     1003  noit_lua_check_deregister_event(ci, cl->pending_event, 0); 
     1004  noit_lua_resume(ci, nargs); 
     1005  lua_pushinteger(L, nargs); 
     1006  return 0; 
     1007} 
     1008 
     1009static int 
     1010nl_waitfor_timeout(eventer_t e, int mask, void *vcl, struct timeval *now) { 
     1011  noit_lua_check_info_t *ci; 
     1012  struct nl_slcl *cl = vcl; 
     1013  struct timeval diff; 
     1014  double p_int; 
     1015 
     1016  ci = get_ci(cl->L); 
     1017  assert(ci); 
     1018  noit_lua_check_deregister_event(ci, e, 0); 
     1019  noit_hash_delete(ci->lmc->pending, cl->inbuff, strlen(cl->inbuff), free, NULL); 
     1020  free(cl); 
     1021  noit_lua_resume(ci, 0); 
     1022  return 0; 
     1023} 
     1024 
     1025static int 
     1026nl_waitfor(lua_State *L) { 
     1027  noit_lua_check_info_t *ci; 
     1028  const char *key; 
     1029  struct nl_slcl *cl; 
     1030  struct timeval diff; 
     1031  eventer_t e; 
     1032  double p_int; 
     1033 
     1034  ci = get_ci(L); 
     1035  assert(ci); 
     1036  if(lua_gettop(L) != 2) { 
     1037    luaL_error(L, "waitfor(key, timeout) wrong arguments"); 
     1038  } 
     1039  p_int = lua_tonumber(L, 2); 
     1040  cl = calloc(1, sizeof(*cl)); 
     1041  cl->free = nl_extended_free; 
     1042  cl->L = L; 
     1043  gettimeofday(&cl->start, NULL); 
     1044 
     1045  key = lua_tostring(L, 1); 
     1046  if(!key) luaL_error(L, "waitfor called without key"); 
     1047  cl->inbuff = strdup(key); 
     1048  if(!noit_hash_store(ci->lmc->pending, cl->inbuff, strlen(cl->inbuff), cl)) { 
     1049    nl_extended_free(cl); 
     1050    luaL_error(L, "waitfor called with duplicate key"); 
     1051  } 
     1052 
     1053  cl->pending_event = e = eventer_alloc(); 
     1054  e->mask = EVENTER_TIMER; 
     1055  e->callback = nl_waitfor_timeout; 
     1056  e->closure = cl; 
     1057  memcpy(&e->whence, &cl->start, sizeof(cl->start)); 
     1058  diff.tv_sec = floor(p_int); 
     1059  diff.tv_usec = (p_int - floor(p_int)) * 1000000; 
     1060  add_timeval(e->whence, diff, &e->whence); 
     1061  noit_lua_check_register_event(ci, e); 
     1062  eventer_add(e); 
     1063  return noit_lua_yield(ci, 0); 
     1064} 
     1065 
    9181066 
    9191067static int 
     
    19262074} 
    19272075static const luaL_Reg noitlib[] = { 
     2076  { "waitfor", nl_waitfor }, 
     2077  { "notify", nl_waitfor_notify }, 
    19282078  { "sleep", nl_sleep }, 
    19292079  { "gettimeofday", nl_gettimeofday }, 
  • src/modules/lua_noit.h

    r2e4d166 r618dd9f  
    5252  lua_State *lua_state; 
    5353  int object_ref; 
     54  noit_hash_table *pending; 
    5455} lua_module_closure_t; 
    5556 
     
    9192  size_t write_goal; 
    9293  eventer_t *eptr; 
     94  eventer_t pending_event; 
    9395 
    9496  int sendto; /* whether this send is a sendto call */