[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Sharing userdata among stats.
- From: Sean Conner <sean@...>
- Date: Wed, 21 Jun 2017 19:33:21 -0400
It was thus said that the Great Laurent FAILLIE once stated:
> Hi,
> I'm building a multi-threaded application and all threads carry their own
> stat.Now, I have to create an object to share data among those stats,
> named SelFIFO : this object is NEVER subject to be collected, mutex are
> handled at C side and slaves only get a C pointer to userdata.
By "stat" do you mean "Lua state"?
> My concern is "how can I insert this pointer to slave stats ?".
> So, in the main thread, this object is created like that :
> struct SelFIFO *q = (struct SelFIFO *)lua_newuserdata(L, sizeof(struct SelFIFO));
> assert(q);
> luaL_getmetatable(L, "SelFIFO");
> lua_setmetatable(L, -2);
> ...
> but, in the slave thread, I got only 'q' pointer.How can I push it in slave's stat ?How can I associate a "SelFIFO" to it ?
> Thanks
> Laurent
> ps: full source code is https://github.com/destroyedlolo/Selene/blob/master/src/SelFIFO.c
Some random comments: you don't need checkSelFIFO()---luaL_checkudata()
will do what you want. Second, DO NOT USE assert() TO CHECK THE RETURN CODE
FOR FUNCTIONS! In particular, this is wrong:
assert(q->name = strdup(n));
Unless you are coding in C++ (and you are not), you do not need to cast
the return code from lua_newuserdata() or any other function that returns a
void *. In fact, you should NOT do that as it can hide bugs.
The easiest way to get what you want is to change sff_create():
static int sff_create(lua_State *L)
{
const char *n = luaL_checkstring(L,1);
char *copy;
struct SelFIFO **q = lua_newuserdata(L,sizeof(struct SelFIFO **));
/*-------------------------------------
; copy the string from Lua and bail if we can't copy it
;------------------------------------------------------*/
copy = strdup(n);
if (copy == NULL)
{
lua_pushnil(L);
return 1;
}
/*------------------------------------------------
; allocate memory for the SelFIFO. Bail if we can't create it.
;-------------------------------------------------------------*/
*q = calloc(1,sizeof(struct SelFIFO));
if (*q == NULL)
{
lua_pushnil(L);
return 1;
}
pthread_mutex_init(&q->mutex,NULL);
q->h = hash(n);
q->name = copy;
q->first = NULL;
q->last = NULL;
q->next = firstFifo;
firstFifo = q;
return 1;
}
Then sff_find() becomes:
static int sff_find(lua_State *L)
{
const char *n = luaL_checkstring(L,1);
int h = hash(n);
for (struct SelFIFO *p = firstFifo ; p ; p = p->next)
{
if ((h == p->h) && (strcmp(n,p->name) == 0))
{
struct SelFIFO **q = lua_newuserdata(L,sizeof(struct SelFIFO **));
*q = p;
return 1;
}
}
return 0;
}
By using a pointer-to-a-pointer, it's easier to push the FIFO into other
states.
-spc (Hope this helps some)