lua-users home
lua-l archive

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


On Sunday 03, C++ RTMP Server wrote:
> Hi,
> 
> Thank you for your inputs.
> 
> LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
> Creates a new, independent state. Returns NULL if cannot create the state
> (due to lack of memory). The argument f is the allocator function; Lua
> does all memory allocation for this state through this function. The
> second argument, ud, is an opaque pointer that Lua simply passes to the
> allocator in every call
> 
> and the next one:
> LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
> Returns the memory-allocation function of a given state. If ud is not NULL,
> Lua stores in *ud the opaque pointer passed to lua_newstate.
> 
> It doesn't say anything about the lifetime of ud. Since the lua_newstate
> doc clearly states that "ud, is an opaque pointer that Lua simply passes
> to the allocator in every call" I presume it MUST preserve it for the
> lifetime of lua_State. The end result is exactly what I need at
> 1-function-call-distance without tempering with the stack like it is
> required if I would want to keep my opaque pointer in the global index.

The reason I don't recommend that method, is that I see it as a hack (using 
something for what it was not intended).  You may run into problems with this 
solution later.  For example if you decide to later use multiple coroutines in 
one lua_State instead of creating multiple lua_State objects, then you will be 
restricted to only one pointer value for all coroutines.

> Moreover, another reason against keeping it in the global index is that I
> don't want lua script having access to that pointer, not even seeing it,
> let alone playing around with it. It only makes sense for the C/C++ side.

The lua code wouldn't have access to the pointer stored in the extra space.

> Another thing is that I only need a pointer so void * is perfect for my
> needs. Why should I temper with the internals of the lib? Can you confirm
> that my logic is ok?

If you want to use the standard Lua VM library without modifications, then you 
can't use the extra space feature.  It is up to you to decide which method you 
use to do what you need.

It is not un-common for projects to embed a customized version of Lua VM core.  
Lua is small enough that this doesn't add a burden on the main project.

> 
> On Apr 3, 2011, at 5:23 AM, Robert G. Jakabosky wrote:
> > On Saturday 02, C++ RTMP Server wrote:
> >> On Apr 3, 2011, at 2:42 AM, Peter Cawley wrote:
> >>> On Sun, Apr 3, 2011 at 12:40 AM, C++ RTMP Server
> >>> <crtmpserver@gmail.com>
> > 
> > wrote:
> >>>> However, I didn't find any way of pulling it out from a lua_State.
> >>> 
> >>> lua_getallocf
> >> 
> >> Jackpot!!! That's exactly what I needed :)
> > 
> > I don't recommend messing with allocator's userdata value.  There is a
> > better option for doing what you want.
> > 
> > In the luaconf.h redefine these:
> > 
> > #define LUAI_EXTRASPACE  sizeof(void *) /* or the size of your custom
> > state */
> > 
> > #define LUA_TO_CUSTOM_STATE(L) ((((unsigned char *)L) - LUAI_EXTRASPACE))
> > inline void init_custom_state(lua_State *L) {
> > 
> >  void **custom_state = LUA_TO_CUSTOM_STATE(L);
> >  *custom_state = NULL;
> >  /* or allocate your custom state. */
> > 
> > }
> > 
> > inline void cleanup_custom_state(lua_State *L) {
> > 
> >  void **custom_state = LUA_TO_CUSTOM_STATE(L);
> >  if(*custom_state) free(*custom_state);
> > 
> > }
> > 
> > inline void copy_custom_state(lua_State *L, lua_State *L1) {
> > 
> >  void **custom_state = LUA_TO_CUSTOM_STATE(L);
> >  void **custom_state1 = LUA_TO_CUSTOM_STATE(L1);
> >  *custom_state1 = *custom_state;
> >  /* or allocate a new custom state. */
> > 
> > }
> > 
> > /* these are for the main states. */
> > #define luai_userstateopen(L)		init_custom_state(L)
> > #define luai_userstateclose(L)		cleanup_custom_state(L)
> > /* these are for lua threads (i.e. coroutines) */
> > #define luai_userstatethread(L,L1)	copy_custom_state(L, L1)
> > #define luai_userstatefree(L)		((void)L)
> > /* you might not need these. */
> > #define luai_userstateresume(L,n)	((void)L)
> > #define luai_userstateyield(L,n)	((void)L)
> > 
> > Now you can always get your custom state object from a lua state pointer
> > using the LUA_TO_CUSTOM_STATE(L) macro.  Note that you could pre-append
> > your custom state object to have a 1-to-1 mapping both ways.  Remember
> > that coroutines have there own lua_State object, which is different from
> > the main lua_State.
> 
> ------
> Eugen-Andrei Gavriloaie
> Web: http://www.rtmpd.com


-- 
Robert G. Jakabosky