lua-users home
lua-l archive

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


On Friday 02, Alex Davies wrote:
> Sounds interesting, I'm surprised that's the only place you ran in to any
> problems. Just so you know, the next version of lua features an emergency
> garbage collector when a request cannot be satisfied. I don't know whether
> this is the same as a full collectgarbage, or if it just finishes the
> current phase or what.
I saw the emergency garbage collector in the feature list for Lua 5.2, after 
fixing this bug.  Also I just read an old-post(June 2006) from the mailling 
list saying that there would be a problem with allocating tables if the GC 
was called after a failed allocation.  I will be doing more testing.

> Just out of curiousity ;) what happens if the second request fails as well
> and an error is thrown? I assume in this obscure case the "used" value
> would be incorrect - doubt it would be a problem but just something to
> consider before making any assumptions about used.
If the GC call doesn't free enough memory then the allocator resets the "used" 
value and returns NULL (and that will cause an error to be thrown).  Also I 
have an assert(used == 0) that is checked right after calling lua_close(L) to 
make sure all allocated memory is correctly accounted for.

Here is the simplified code for the allocator:

old_used = memused; /* save old memused. */
memused -= osize;
if(nsize == 0) {
  free(ptr);
  return NULL;
}
memused += nsize;
if(nsize > osize && memused >= max_memused) {
  memused = old_size; /* restore old memused. */
  lua_gc(L, LUA_GCCOLLECT, 0);
  /* check memory usage again. */
  old_size = memused;
  memused -= osize;
  memused += nsize;
  if(memused >= max_memused) {
    /* GC wasn't able to free enough memory.  Fail allocation.*/
    memused = old_size;
    return NULL;
  }
}
return realloc(ptr, nsize);

-- 
Robert G. Jakabosky