lua-users home
lua-l archive

Re: Multiple functions: was the gc

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


However, I think wrapping your scripts should work:
return function(...)
-- original script goes here
end
Then, you can lua_load the script once and lua_call it each time you want a fresh function instance. That'll be dead fast.
[snip snip]
But that only works for a single level. Any functions _called_ by that
closure are still bound to the original environment. In this case,
calling "bar" puts you right back where you started.
Attached is another approach. Give it a spin and then try to unravel what's happening! :-)
--
Wim
--
-- thread local globals ?!?
--
local getfenv = getfenv
-- get thread local global
local function getglobal(self, index)
	return getfenv(0)[index]
end
-- set thread local global
local function setglobal(self, index, value)
	getfenv(0)[index] = value
end
-- reroute fun to thread local globals
function tlg(fun)
	setfenv(fun, setmetatable({}, {
		__index = getglobal,
		__newindex = setglobal,
	}))
end
-- helper to prepare a coroutine with a separate environment
-- (cannot be done from Lua otherwise.)
function start(fun, name)
	return coroutine.create(function()
		-- set some thread local globals
		setfenv(0, setmetatable({
			name = name,
			j = 1,
		}, { __index = _G}))
		-- start fun
		fun()
	end)
end
-- OK, let's give it a spin
-- here's some innocent volunteer...
-- note that it exclusively uses globals.
function count()
	for i = 1, 4 do
		print("in thread " .. name .. ", j = " .. j)
		j = j + 1
		coroutine.yield()
	end
	print("thread " .. name .. " is done!")
end
-- reroute to thread local globals
tlg(count)
-- prepare two threads to run function count.
t1 = start(count, "t1")
t2 = start(count, "t2")
-- execute in some random order and see what happens...
coroutine.resume(t1)
coroutine.resume(t1)
coroutine.resume(t1)
coroutine.resume(t2)
coroutine.resume(t1)
coroutine.resume(t2)
coroutine.resume(t1)
coroutine.resume(t2)
coroutine.resume(t2)
coroutine.resume(t2)

AltStyle によって変換されたページ (->オリジナル) /