#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#define NGX_LUA_THREAD_KEY "NGX_LUA_THREAD_KEY"
typedef struct {
lua_State *l;
} ngx_lua_t;
typedef struct {
lua_State *l;
int ref;
} ngx_lua_thread_t;
ngx_lua_t *
ngx_lua_create(void)
{
ngx_lua_t *lua;
lua_State *l;
lua = (ngx_lua_t *) malloc(sizeof(ngx_lua_t));
if (lua == NULL) {
return NULL;
}
memset(lua, 0, sizeof(ngx_lua_t));
l = luaL_newstate();
if (l == NULL) {
free(lua);
return NULL;
}
luaL_openlibs(l);
lua_newtable(l);
lua_setfield(l, LUA_REGISTRYINDEX, NGX_LUA_THREAD_KEY);
lua->l = l;
return lua;
}
void
ngx_lua_destroy(ngx_lua_t *lua)
{
if (lua->l != NULL) {
lua_close(lua->l);
}
free(lua);
}
ngx_lua_thread_t *
ngx_lua_thread_create(ngx_lua_t *lua)
{
int ref;
lua_State *l;
ngx_lua_thread_t *thr;
thr = (ngx_lua_thread_t *) malloc(sizeof(ngx_lua_thread_t));
if (thr == NULL) {
return NULL;
}
memset(thr, 0, sizeof(ngx_lua_thread_t));
lua_pushstring(lua->l, NGX_LUA_THREAD_KEY);
lua_rawget(lua->l, LUA_REGISTRYINDEX);
l = lua_newthread(lua->l);
if (l == NULL) {
lua_pop(lua->l, 1);
free(thr);
return NULL;
}
ref = luaL_ref(lua->l, -2);
if (ref == LUA_REFNIL) {
lua_pop(lua->l, 2);
free(thr);
return NULL;
}
lua_pop(lua->l, 1);
thr->l = l;
thr->ref = ref;
return thr;
}
void
ngx_lua_thread_destroy(ngx_lua_t *lua, ngx_lua_thread_t *thr)
{
lua_pushstring(lua->l, NGX_LUA_THREAD_KEY);
lua_rawget(lua->l, LUA_REGISTRYINDEX);
luaL_unref(lua->l, -1, thr->ref);
lua_pop(lua->l, 1);
free(thr);
}
int
main(int argc, char *argv[])
{
ngx_lua_t *lua;
ngx_lua_thread_t *thr;
lua = ngx_lua_create();
if (lua == NULL) {
return 1;
}
printf("lua:%p\n", lua);
thr = ngx_lua_thread_create(lua);
if (thr == NULL) {
ngx_lua_destroy(lua);
return 1;
}
printf("lua:%p thr:%p\n", lua, thr);
ngx_lua_thread_destroy(lua, thr);
ngx_lua_destroy(lua);
return 0;
}