static int ts_lua_cache_close(lua_State *L) { int n; ts_lua_cont_info *ci; ts_lua_cache_info *info; ci = ts_lua_get_cont_info(L); if (ci == NULL) return 0; n = lua_gettop(L); if (n < 1) { return luaL_error(L, "'ts.cache_close' requires parameter"); } /* table */ if (!lua_istable(L, 1)) { return luaL_error(L, "'ts.cache_close' first param is not valid"); } lua_pushlstring(L, "info", sizeof("info") - 1); lua_gettable(L, 1); if (!lua_islightuserdata(L, -1)) { return luaL_error(L, "'ts.cache_close' first param is not valid"); } info = (ts_lua_cache_info*)lua_touserdata(L, -1); lua_pop(L, 1); ts_lua_release_cache_info(info, 0); return 0; }
static int ts_lua_sleep(lua_State *L) { int sec; TSAction action; TSCont contp; ts_lua_async_item *ai; ts_lua_cont_info *ci; ci = ts_lua_get_cont_info(L); if (ci == NULL) return 0; sec = luaL_checknumber(L, 1); if (sec < 1) { sec = 1; } contp = TSContCreate(ts_lua_sleep_handler, ci->mutex); action = TSContSchedule(contp, sec * 1000, TS_THREAD_POOL_DEFAULT); ai = ts_lua_async_create_item(contp, ts_lua_sleep_cleanup, (void *)action, ci); TSContDataSet(contp, ai); return lua_yield(L, 0); }
static int ts_lua_schedule(lua_State *L) { int sec; int type; int entry; ts_lua_http_ctx *actx; int n; TSCont contp; ts_lua_cont_info *ci; ts_lua_cont_info *nci; ci = ts_lua_get_cont_info(L); if (ci == NULL) return 0; entry = lua_tointeger(L, 1); sec = luaL_checknumber(L, 2); if (sec < 1) { sec = 0; } type = lua_type(L, 3); if (type != LUA_TFUNCTION) return 0; n = lua_gettop(L); if (n < 3) { TSError("[ts_lua] ts.http.schedule need at least three params"); return 0; } // TO-DO unset the original context in L actx = ts_lua_create_async_ctx(L, ci, n); contp = TSContCreate(ts_lua_schedule_handler, ci->mutex); TSContDataSet(contp, actx); nci = &actx->cinfo; nci->contp = contp; nci->mutex = ci->mutex; TSContSchedule(contp, sec * 1000, entry); return 0; }
static int ts_lua_cache_remove(lua_State *L) { const char *keystr, *optstr; size_t key_len, opt_len; int n; TSCont contp; TSCacheKey key; TSAction action; ts_lua_cont_info *ci; ts_lua_async_item *ai; ts_lua_cache_info *info; ci = ts_lua_get_cont_info(L); if (ci == NULL) return 0; n = lua_gettop(L); if (n < 1) { return luaL_error(L, "'ts.cache_remove' requires parameter"); } /* keystr */ if (!lua_isstring(L, 1)) { return luaL_error(L, "'ts.cache_remove' first param is not string"); } keystr = luaL_checklstring(L, 1, &key_len); optstr = NULL; opt_len = 0; /* option */ if (n >= 2 && lua_isstring(L, 2)) { optstr = luaL_checklstring(L, 2, &opt_len);; } key = ts_lua_cache_key_create(keystr, key_len, optstr, opt_len); if (key == NULL) { return luaL_error(L, "'ts.cache_remove' failed"); } info = (ts_lua_cache_info*)TSmalloc(sizeof(ts_lua_cache_info)); memset(info, 0, sizeof(ts_lua_cache_info)); info->cache_key = key; contp = TSContCreate(ts_lua_cache_remove_handler, ci->mutex); ai = ts_lua_async_create_item(contp, ts_lua_cache_cleanup, info, ci); TSContDataSet(contp, ai); action = TSCacheRemove(contp, key); if (!TSActionDone(action)) { info->cache_action = action; return lua_yield(L, 0); } else { // action done ts_lua_release_cache_info(info, 1); ai->data = NULL; return 0; } }
static int ts_lua_cache_write(lua_State *L) { int64_t length, n; const char *data; size_t dlen; ts_lua_cont_info *ci; ts_lua_cache_info *info; ci = ts_lua_get_cont_info(L); if (ci == NULL) return 0; n = lua_gettop(L); if (n < 2) { return luaL_error(L, "'ts.cache_write' requires parameter"); } /* data */ if (!lua_isstring(L, 2)) { return luaL_error(L, "'ts.cache_write' second param is not string"); } data = luaL_checklstring(L, 2, &dlen); /* length */ length = dlen; if (n >= 3) { if (!lua_isnumber(L, 3)) { return luaL_error(L, "'ts.cache_write' third param is not number"); } length = lua_tonumber(L, 3); if (length <= 0) { return luaL_error(L, "'ts.cache_write' third param is a not valid number"); } if (length > dlen) length = dlen; } /* table */ if (!lua_istable(L, 1)) { return luaL_error(L, "'ts.cache_write' first param is not valid"); } lua_pushlstring(L, "info", sizeof("info") - 1); lua_gettable(L, 1); if (!lua_islightuserdata(L, -1)) { return luaL_error(L, "'ts.cache_write' first param is not valid"); } info = (ts_lua_cache_info*)lua_touserdata(L, -1); lua_pop(L, 1); if (info->optype != TS_LUA_CACHE_WRITE) { return luaL_error(L, "'ts.cache_write' is writing to invalid vc"); } if (info->err) { lua_pushnil(L); return 1; } info->need += length; info->current_handler = &ts_lua_cache_handle_write; TSIOBufferWrite(info->ioh.buffer, data, length); if (info->ioh.vio == NULL) { info->ioh.vio = TSVConnWrite(info->cache_vc, info->contp, info->ioh.reader, INT64_MAX); } else { TSVIOReenable(info->ioh.vio); } info->wait = 1; return lua_yield(L, 0); }
static int ts_lua_cache_read(lua_State *L) { int64_t length, n, avail; char *dst; ts_lua_cont_info *ci; ts_lua_cache_info *info; ci = ts_lua_get_cont_info(L); if (ci == NULL) return 0; n = lua_gettop(L); if (n < 1) { return luaL_error(L, "'ts.cache_read' requires parameter"); } /* length */ if (n >= 2) { if (!lua_isnumber(L, 2)) { return luaL_error(L, "'ts.cache_read' second param is not number"); } length = lua_tonumber(L, 2); if (length <= 0) { return luaL_error(L, "'ts.cache_read' second param is a not valid number"); } } else { length = INT64_MAX; } /* table */ if (!lua_istable(L, 1)) { return luaL_error(L, "'ts.cache_read' first param is not valid"); } lua_pushlstring(L, "info", sizeof("info") - 1); lua_gettable(L, 1); if (!lua_islightuserdata(L, -1)) { return luaL_error(L, "'ts.cache_read' first param is not valid"); } info = (ts_lua_cache_info*)lua_touserdata(L, -1); lua_pop(L, 1); if (info->hit == 0) { return luaL_error(L, "'ts.cache_read' is reading from unhit doc"); } if (info->optype != TS_LUA_CACHE_READ) { return luaL_error(L, "'ts.cache_read' is reading from invalid vc"); } if (info->eof || info->err) { lua_pushnil(L); return 1; } if (length != INT64_MAX) { info->need += length; } else { info->need = INT64_MAX; } info->current_handler = &ts_lua_cache_handle_read; avail = TSIOBufferReaderAvail(info->reserved.reader); if (avail + info->already >= info->need) { n = info->need - info->already; dst = (char*)TSmalloc(n); IOBufferReaderCopy(info->reserved.reader, dst, n); lua_pushlstring(L, (char*)dst, n); TSfree(dst); info->already = info->need; TSIOBufferReaderConsume(info->reserved.reader, n); return 1; } if (info->ioh.vio == NULL) { info->ioh.vio = TSVConnRead(info->cache_vc, info->contp, info->ioh.buffer, INT64_MAX); } else { TSVIOReenable(info->ioh.vio); } info->wait = 1; return lua_yield(L, 0); }
static int ts_lua_cache_open(lua_State *L) { const char *keystr, *optstr; size_t key_len, opt_len; int operate, n; TSCont contp; TSCacheKey key; TSAction action; ts_lua_cont_info *ci; ts_lua_async_item *ai; ts_lua_cache_info *info; ci = ts_lua_get_cont_info(L); if (ci == NULL) return 0; n = lua_gettop(L); if (n < 2) { return luaL_error(L, "'ts.cache_open' requires parameter"); } /* keystr */ if (!lua_isstring(L, 1)) { return luaL_error(L, "'ts.cache_open' first param is not string"); } else if (!lua_isnumber(L, 2)) { return luaL_error(L, "'ts.cache_open' second param is not TS_LUA_CACHE_READ/TS_LUA_CACHE_WRITE"); } keystr = luaL_checklstring(L, 1, &key_len); operate = lua_tonumber(L, 2); if (operate != TS_LUA_CACHE_READ && operate != TS_LUA_CACHE_WRITE) { return luaL_error(L, "'ts.cache_open' second param is not TS_LUA_CACHE_READ/TS_LUA_CACHE_WRITE"); } optstr = NULL; opt_len = 0; /* option */ if (n >= 3 && lua_isstring(L, 3)) { optstr = luaL_checklstring(L, 3, &opt_len); } key = ts_lua_cache_key_create(keystr, key_len, optstr, opt_len); if (key == NULL) { return luaL_error(L, "'ts.cache_open' failed"); } info = (ts_lua_cache_info*)TSmalloc(sizeof(ts_lua_cache_info)); memset(info, 0, sizeof(ts_lua_cache_info)); info->cache_key = key; info->optype = operate; contp = TSContCreate(ts_lua_cache_main_handler, ci->mutex); ai = ts_lua_async_create_item(contp, ts_lua_cache_cleanup, info, ci); TSContDataSet(contp, ai); info->contp = contp; info->ioh.buffer = TSIOBufferCreate(); info->ioh.reader = TSIOBufferReaderAlloc(info->ioh.buffer); if (operate == TS_LUA_CACHE_READ) { info->reserved.buffer = TSIOBufferCreate(); info->reserved.reader = TSIOBufferReaderAlloc(info->reserved.buffer); info->current_handler = &ts_lua_cache_open_read; action = TSCacheRead(contp, key); } else { info->current_handler = &ts_lua_cache_open_write; action = TSCacheWrite(contp, key); } if (TSActionDone(action)) { // done return 1; } else { // undone info->cache_action = action; return lua_yield(L, 0); } }