lua-users home
lua-l archive

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


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)