[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: C API question
- From: Mark Hamburg <mark@...>
- Date: Wed, 12 Jan 2011 17:31:11 -0800
References are dangerous for a variety of reasons relating to multi-threading, uncollectable reference cycles, etc.
There are better solutions than references for the tasks that references are being used for and these solutions are much less susceptible to these problems.
The entire code for references is, I believe, here:
/* compatibility with ref system */
/* pre-defined references */
#define LUA_NOREF (-2)
#define LUA_REFNIL (-1)
#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
(lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
/* convert a stack index to positive */
#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
lua_gettop(L) + (i) + 1)
#define FREELIST_REF 0 /* free list of references */
LUALIB_API int luaL_ref (lua_State *L, int t) {
int ref;
t = abs_index(L, t);
if (lua_isnil(L, -1)) {
lua_pop(L, 1); /* remove from stack */
return LUA_REFNIL; /* `nil' has a unique fixed reference */
}
lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */
lua_pop(L, 1); /* remove it from stack */
if (ref != 0) { /* any free element? */
lua_rawgeti(L, t, ref); /* remove it from list */
lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
}
else { /* no free elements */
ref = (int)lua_objlen(L, t);
ref++; /* create new reference */
}
lua_rawseti(L, t, ref);
return ref;
}
LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
if (ref >= 0) {
t = abs_index(L, t);
lua_rawgeti(L, t, FREELIST_REF);
lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */
lua_pushinteger(L, ref);
lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
}
}
This all goes through the public Lua API. So, if you really need to use the old system, it should be pretty trivial to build it into your sources without modifying the Lua distribution. The only thing that would become problematic is if Lua were to start making heavy use of the integer-keyed portion of the registry in such a way as to break the reference logic.
Mark
- References:
- Re: C API question, Mark Hamburg
- Re: C API question, Roberto Ierusalimschy
- Re: C API question, Jerome Vuarand
- Re: C API question, Roberto Ierusalimschy
- Re: C API question, Daniel Silverstone
- Re: C API question, Doug Currie
- Re: C API question, Patrick Donnelly
- Re: C API question, Doug Currie
- Re: C API question, Roberto Ierusalimschy
- Re: C API question, liam mail
- Re: C API question, Roberto Ierusalimschy
- Re: C API question, Mark Hamburg
- Re: C API question, liam mail
- Re: C API question, Greg Falcon
- Re: C API question, liam mail