lua-users home
lua-l archive

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

On Tue, Jan 20, 2009 at 8:48 PM, John Belmonte wrote:
> On Tue, Jan 20, 2009 at 5:56 PM, Asko Kauppi wrote:
>> In other words, what exactly does it _not_ cover, in your and/or David's
>> opinion?  Give us a list.
> Repeated from the previous message for you:
>  Many applications expose scarce resources to the scripting
>  environment such as locks; handles for files, memory, and database
>  transactions; etc.  Such resources need to be released promptly and
>  deterministically after use, and despite any exceptional condition in
>  the program.  Of course this can be accomplished with Lua as it is,
>  but the resulting code is hard to follow [1], highly error prone, and
>  makes heavy use of protected calls-- limiting potential use of
>  coroutines.

Decision #1 proposes some more convenient mechanism for deterministic
resource cleanup (a.k.a. "deterministic finalization").  In contrast,
Lua's garbage collector, like most garbage collectors, provides
non-deterministic resource cleanup through finalizers, which in Lua
are the "__gc" metamethods on userdata (accessible in pure Lua code
only through newproxy[8]).  The finalizer of an object typically
closes any resources the object owns, such as to release memory or
close a file handle.  The potential problem is that Lua can delay
running the finalizers as long as it wants to or until you explicitly
call collectgarbage().  In many cases, such as with managed resources
(i.e. memory managed by Lua), this may not be a problem.  In other
cases, as in non-managed resources noted by John above,
non-deterministic resource cleanup can negatively affect program
correctness.  A typical solution to this is for the object to provide
a manually callable dispose method that releases resources.  In the
Lua file object, this is the file:close() method.  This may be fine
except when a block of code contains a number of exit locations via
returns or exceptions.  You may need to take care to call the dispose
method prior to each return and after each exception (i.e. following a
pcall).  In Lua, numerous pcalls and disposals before returns can be

It's a well recognized problem.  Some .NET descriptions are in [2-5]
for background (.NET is a garbage collected framework that provides a
special mechanism for deterministic finalization).  C# and Python
provide the using and with clauses.  D provides the scope statement.
Java provides a somewhat invasive try/finally.  Traditionally
non-garbage-collected languages may provide other ways of
deterministic cleanup: C++ has RAII and Perl 5 has reference

Now, personally, in practice, I've only found myself wanting this time
of capability in Lua on a few occasions (but perhaps others with
different applications will have greater need for it):

  - closing file handles upon exceptions
  - closing COM objects on exceptions
  - releasing native OS handles on exceptions, e.g. as once in
  - and if I used Lua more for database and socket work, quite
possibly that too.

Workarounds I've used are explicit collectgarbage() calls judiciously
placed, adding pcalls (often ugly, affects error tracebacks, and can
conflict with coroutines), and ignoring the problem (sometimes
acceptable).  In the case of file objects, they return on error
(rather than raise like in Java), so pcall can often be avoided unless
intervening code raises errors, but you can still need to explicitly
close on scope exits.

I'll also add that exception safety in Lua may require some practical
assumptions concerning out-of-memory errors[6][7].