Changeset 99740787fcf7e1df9a88ee9072d83bd8741ebea7

Show
Ignore:
Timestamp:
06/03/08 14:19:31 (6 years ago)
Author:
Theo Schlossnagle <jesus@omniti.com>
git-committer:
Theo Schlossnagle <jesus@omniti.com> 1212502771 +0000
git-parent:

[9349d12fbdff88611b594e12e5a3025bf1e651de]

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

use references and garbage collection to implement thread abortion. refs #28

Files:

Legend:

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

    r9349d12 r9974078  
    1717static noit_log_stream_t nlerr = NULL; 
    1818static noit_log_stream_t nldeb = NULL; 
     19static noit_hash_table noit_coros = NOIT_HASH_EMPTY; 
    1920 
    2021noit_lua_check_info_t * 
    2122get_ci(lua_State *L) { 
    2223  noit_lua_check_info_t *v = NULL; 
    23   lua_getglobal(L, "noit_coros"); 
    24   lua_pushthread(L); 
    25   lua_gettable(L, -2); 
    26   if(lua_isuserdata(L, -1)) v = lua_touserdata(L, -1); 
    27   lua_pop(L, 1); 
    28   return v; 
     24  if(noit_hash_retrieve(&noit_coros, (const char *)&L, sizeof(L), (void **)&v)) 
     25    return v; 
     26  return NULL; 
    2927} 
    3028 
     
    435433       * to wake up the coro... 
    436434       */ 
    437       return 0; 
     435      lua_gc(ci->lmc->lua_state, LUA_GCCOLLECT, 0); 
     436      goto done; 
    438437    default: /* Errors */ 
    439       ci->current.status = "unknown error"; 
     438      noitL(nlerr, "lua resume returned: %d\n", result); 
     439      ci->current.status = ci->timed_out ? "timeout" : "unknown error"; 
    440440      ci->current.available = NP_UNAVAILABLE; 
    441441      ci->current.state = NP_BAD; 
     
    453453  noit_lua_module_cleanup(ci->self, ci->check); 
    454454  check->flags &= ~NP_RUNNING; 
    455   return 0; 
     455 
     456 done: 
     457  lua_gc(ci->lmc->lua_state, LUA_GCCOLLECT, 0); 
     458  return result; 
    456459} 
    457460static int 
     
    465468  noit_lua_check_deregister_event(ci, e); 
    466469  if(ci->coro_state) { 
    467     lua_pushnil(ci->coro_state); 
    468     noit_lua_resume(ci, 1); 
     470    /* Our coro is still "in-flight". To fix this we will unreference 
     471     * it, garbage collect it and then ensure that it failes a resume 
     472     */ 
     473    lua_getglobal(ci->lmc->lua_state, "noit_coros"); 
     474    luaL_unref(ci->lmc->lua_state, -1, ci->coro_state_ref); 
     475    lua_pop(ci->lmc->lua_state, 2); 
     476    lua_gc(ci->lmc->lua_state, LUA_GCCOLLECT, 0); 
     477    assert(2 == noit_lua_resume(ci, 0)); 
    469478  } else { 
    470479    noit_lua_log_results(ci->self, ci->check); 
     
    506515  eventer_add(e); 
    507516 
     517  ci->lmc = lmc; 
    508518  lua_getglobal(L, "noit_coros"); 
    509519  ci->coro_state = lua_newthread(L); 
    510   lua_pushlightuserdata(L, ci); 
    511   lua_settable(L, -3); 
    512   lua_pop(L, 1); 
     520  noit_hash_store(&noit_coros, 
     521                  (const char *)&ci->coro_state, sizeof(ci->coro_state), 
     522                  ci); 
     523  ci->coro_state_ref = luaL_ref(L, -2); 
     524  lua_pop(L, 1); /* pops noit_coros */ 
    513525 
    514526  SETUP_CALL(ci->coro_state, "initiate", goto fail); 
  • src/modules/lua_noit.h

    r5bf243f r9974078  
    3434  lua_module_closure_t *lmc; 
    3535  lua_State *coro_state; 
     36  int coro_state_ref; 
    3637  struct timeval finish_time; 
    3738  stats_t current;