lua-users home
lua-l archive

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

>   A few months ago I wrote some code to recursively dive into directories,
> using something like:
> 	[...]
>   I was exhausting file descriptors before my program finished [1].  Upon
> investigation, it was because iterating over a directory uses a file
> descriptor, and because GC had yet to kick in, I had a bazillion open
> directories.  I had to change the iterator to close and release the
> directory upon finishing instead of relying upon the GC.  And this is in
> what I consider library code.

I think a few rules could greatly improve things. Unfortunately, I was
not following them :-)

- As Tomas pointed out, iterators should release their resources as soon
as they reach the last element. Sadly, my implementation of a directory
iterator in PiL does not do that; but the implementation of io.lines in
the standard library does :-)

- Routines that create resources could do an "emergency collection"
in case the creation fails. For instance, I have just added the
following code to the IO library:

static FILE *trytoopen (lua_State *L, const char *path, const char *mode) {
  FILE *f = fopen(path, mode);
#if defined(EMFILE)  /* EMFILE is not ANSI C */
  if (f == NULL && errno == EMFILE) {  /* too many open files? */
    lua_gc(L, LUA_GCCOLLECT);  /* try to close some files with a GC */
    f = fopen(path, mode);  /* try to open again */
  (void)L;  /* to avoid warnings */
  return f;

These rules put no burden on library users, only on library implementers.

-- Roberto