lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Or you can declare that all lua_States in your program are inside
LuaPrivateState, so the outer struct can be accessed by pointer
conversion:

struct LuaPrivateState *state = (struct LuaPrivateState *)((char
*)lua_state - offsetof(struct LuaPrivateState, pVM));


Best regards,
Mikhail Gusarov.


On Sat, Aug 31, 2013 at 11:07 PM, Tim Hill <drtimhill@gmail.com> wrote:
> I'm currently working on the third major project with Lua as an integral part, and in each project we've found it necessary to wrap a Lua_State* inside another structure that contains ancillary information (some statistics, a mutex, linked list pointers etc etc). I'm sure we're not the only ones doing this…
>
> struct LuaPrivateState {
>         lua_State* pVM;
>         // Other state here...
> }
>
> The problem with this, is that when Lua calls out to a support C function, that function gets the usual Lua_State* pointer (so it can access the Lua stack etc), but for some of these functions it is necessary to also access the ancillary state that is "outside" the Lua_State itself.
>
> The problem, of course, is how to convert a Lua_State pointer to the ancillary state (LuaPrivateState*) pointer. There are a bunch of ways to do this:
>
> -- Put it in a global. Yuck and doesn't work when you have lots of states.
>
> -- Stick it in the Lua Registry as a light userdata under a well-known key. This works, but is somewhat expensive compared to (say) a simple C pointer de-reference. In some cases the table lookup may be the bulk of the execution time of the C function.
>
> -- Store it in TLS (thread local storage) so the thread running Lua can find it. Works, but again not cheap, and has to be setup dynamically when threads run Lua states. Also TLS is not very portable across platforms.
>
> -- Store it in some structure indexed by the Lua_State pointer (e.g. an RB tree). Again, works but seems overkill for a pointer de-reference.
>
> -- Play tricks with the Lua custom memory allocator, which allows an arbitrary void* to be associated with each Lua_State as a side-effect of providing a custom memory allocator. Fast, but kinda abusing a Lua facility.
>
> I'm sure there are others as well.
>
> However, it would be nice if Lua just provided a simple void* pointer that could be associated with each Lua_State (presumably set when the state was created) and extracted via a nice and fast lua_getstateptr() API (or, more probably, a macro that was pretty near instant). Considering all the other nice "helpers" Lua provides for embedding (Register, userdata etc), I'm a bit surprised that this isn't in the API already.
>
> Anyone else see this as a useful (and cheap) nice to have in the API?
>
> --Tim
>
>