[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Multiple functions: was the gc
- From: Wim Couwenberg <w.couwenberg@...>
- Date: Tue, 22 Aug 2006 21:16:46 +0200
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)