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 Rena once stated:
> I have a module that allows Lua to create some objects. Each of those
> objects has its own OS thread doing some work. Even if the Lua state that
> created them discards the reference to them, I want those threads to run to
> completion. That's simple enough; just make the Lua objects only pointers
> to them, and don't delete them when the reference is collected.

  Are you using ptheads?  If so, how are you handling the thread finishing? 
Are you calling pthread_join()?  Or are they detachable and can exit without
waiting for them to finish?

> I don't think it'd be terribly easy for them to clean themselves up,
> either - the thread that created them should be the one to delete them (or
> else the design becomes a lot more complicated).

  Why is this the case?  If you have control over the code for the threads,
then I don't see why they can't clean up the resources themselves, unless
it's part of some larger shared state that the parent thread needs to
handle.  But then again, if the thread can continue past Lua gc, then it
sounds like they're detached and you don't do a pthread_join() (or
evquivalent if you aren't using pthreads).  
  
> I feel like one method might be to take advantage of __gc: create some
> object in the registry (or even only on the stack) and then immediately
> discard all references to it, so that it gets collected on the next cycle.
> Then in that __gc callback, prune any objects ready to be discarded, and
> push (and immediately discard again) another reference to this placeholder
> object (or a new one), so that __gc fires again on the next cycle. But I'm
> not sure this will work (the manual mentions something about finalizers
> only running once), and it seems like an ugly hack.

  Some code for Lua 5.2 was presented just recently that did something (to
monitor memory usage):

	do
	  -- track memory use
	  local mt = {__gc = function (u)
	    if collectgarbage("count") > 10000 then
	      error("script uses too much memory")
	    else
	      setmetatable({}, getmetatable(u))
	    end
	  end}
	  setmetatable({}, mt)
	end

But instead of calling collectgarbage(), you could call your clean up
method.  It would probably look something like:

	local mt = 
	{ 
	  __gc = function(u)
	    call_magic_cleanup_stuff()
	    setmetatable({},getmetatable(u))
	  end
	}

	setmetatable({},mt)

Doing this for Lua 5.1 is not quite as easy, as you need to use a userdata
object (say, a pointer to int) instead of a Lua table, but the concept is
the same.

  -spc