lua-users home
lua-l archive

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


Hi.

I have a really annoying dll problem. I have a C function inside my dll which I’m calling from Lua. Everything goes just fine unless Lua is using more memory than current threshold is before calling C function. In C function garbage collection makes the application crash. If I make Lua collect garbage before calling C function everything goes fine but if I try to collect garbage in beginning of C function everything crashes. I debugged what happens when I try to do garbage collection in start of C Function:

static int l_DisplayFunction(lua_State *L)
{
  lua_setgcthreshold(L, 0);
...


lapi.c:
LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
  lua_lock(L);
  if (cast(lu_mem, newthreshold) > GCscalel(MAX_LUMEM))
    G(L)->GCthreshold = MAX_LUMEM;
  else
    G(L)->GCthreshold = GCunscale(newthreshold);
  luaC_checkGC(L);
...


lgc.c:
void luaC_collectgarbage (lua_State *L) {
  size_t deadmem = mark(L);
  luaC_sweep(L, 0);
...


lgc.c:
void luaC_sweep (lua_State *L, int all) {
  if (all) all = 256;  /* larger than any mark */
  sweeplist(L, &G(L)->rootudata, all);
  sweepstrings(L, all);
...


lgc.c:
static void sweepstrings (lua_State *L, int all) {
  int i;
  for (i=0; i<G(L)->strt.size; i++) {  /* for each list */
    G(L)->strt.nuse -= sweeplist(L, &G(L)->strt.hash[i], all);
...


lgc.c:
static int sweeplist (lua_State *L, GCObject **p, int limit) {
  GCObject *curr;
  int count = 0;  /* number of collected items */
  while ((curr = *p) != NULL) {
    if (curr->gch.marked > limit) {
      unmark(curr);
      p = &curr->gch.next;
    }
    else {
      count++;
      *p = curr->gch.next;
      freeobj(L, curr);
...


lgc.c:
static void freeobj (lua_State *L, GCObject *o) {
  switch (o->gch.tt) {
    case LUA_TPROTO: luaF_freeproto(L, gcotop(o)); break;
    case LUA_TFUNCTION: luaF_freeclosure(L, gcotocl(o)); break;
    case LUA_TUPVAL: luaM_freelem(L, gcotouv(o)); break;
    case LUA_TTABLE: luaH_free(L, gcotoh(o)); break;
    case LUA_TTHREAD: {
      lua_assert(gcototh(o) != L && gcototh(o) != G(L)->mainthread);
      luaE_freethread(L, gcototh(o));
      break;
    }
    case LUA_TSTRING: {
      luaM_free(L, o, sizestring(gcotots(o)->tsv.len));
...


lmem.c:
void *luaM_realloc (lua_State *L, void *block, lu_mem oldsize, lu_mem size) {
  lua_assert((oldsize == 0) == (block == NULL));
  if (size == 0) {
    if (block != NULL) {
      l_free(block, oldsize);        --> Crash


This happens even with a very simple script:
f = loadlib('plot.dll', 'luaopen_plot')

if type(f) == 'function' then
  f()

  Plot.DisplayFunction()
end


I’m using Lua 5.02, Windows XP and Visual Studio .NET 2003 if that information helps. In this environment C functions work fine until there is garbage collection inside C function. Also the same code outside dll (as standalone application) is working with garbage collection. The dll is compiled as Multi-threaded dll. All ideas are welcome.

floru