diff options
author | Steven Barth <steven@midlink.org> | 2008-06-14 14:12:12 +0000 |
---|---|---|
committer | Steven Barth <steven@midlink.org> | 2008-06-14 14:12:12 +0000 |
commit | 855b7582d3576f45693e3a48fdb253c813cf4dce (patch) | |
tree | b912f63dc43f3b696385083542c801dba8c53976 /libs/core | |
parent | 50fd29841540bb8b1735291b72853454679e9e62 (diff) |
* Rewrote Luci to be coroutine-safe allowing the use of non-forking webservers
* Setting base version to 0.7
Diffstat (limited to 'libs/core')
-rw-r--r-- | libs/core/luasrc/init.lua | 2 | ||||
-rw-r--r-- | libs/core/luasrc/util.lua | 79 |
2 files changed, 79 insertions, 2 deletions
diff --git a/libs/core/luasrc/init.lua b/libs/core/luasrc/init.lua index b390df3ac..b4ecb93c1 100644 --- a/libs/core/luasrc/init.lua +++ b/libs/core/luasrc/init.lua @@ -25,5 +25,5 @@ limitations under the License. ]]-- module("luci", package.seeall) -__version__ = "0.6" +__version__ = "0.7" __appname__ = "LuCI" diff --git a/libs/core/luasrc/util.lua b/libs/core/luasrc/util.lua index ad53138e6..fda4563ad 100644 --- a/libs/core/luasrc/util.lua +++ b/libs/core/luasrc/util.lua @@ -36,7 +36,7 @@ function class(base) setmetatable(inst, {__index = class}) if inst.__init__ then - local stat, err = pcall(inst.__init__, inst, ...) + local stat, err = copcall(inst.__init__, inst, ...) if not stat then error(err) end @@ -152,6 +152,12 @@ function pcdata(value) end +-- Returns an error message to stdout +function perror(obj) + io.stderr:write(tostring(obj) .. "\n") +end + + -- Resets the scope of f doing a shallow copy of its scope into a new table function resfenv(f) setfenv(f, clone(getfenv(f))) @@ -255,6 +261,34 @@ function strip_bytecode(dump) end +-- Creates a new threadlocal store +function threadlocal() + local tbl = {} + + local function get(self, key) + local c = coroutine.running() + local thread = coxpt[c] or c or 0 + if not rawget(self, thread) then + rawset(self, thread, {}) + end + return rawget(self, thread)[key] + end + + local function set(self, key, value) + local c = coroutine.running() + local thread = coxpt[c] or c or 0 + if not rawget(self, thread) then + rawset(self, thread, {}) + end + rawget(self, thread)[key] = value + end + + setmetatable(tbl, {__index = get, __newindex = set}) + + return tbl +end + + -- Removes whitespace from beginning and end of a string function trim(str) local s = str:gsub("^%s*(.-)%s*$", "%1") @@ -355,3 +389,46 @@ end function vspairs(t) return _sortiter( t, function (a,b) return t[a] < t[b] end ) end + + +-- Coroutine safe xpcall and pcall versions modified for Luci +-- original version: +-- coxpcall 1.13 - Copyright 2005 - Kepler Project (www.keplerproject.org) +local performResume, handleReturnValue +local oldpcall, oldxpcall = pcall, xpcall +coxpt = {} + +function handleReturnValue(err, co, status, ...) + if not status then + return false, err(debug.traceback(co, (...)), ...) + end + if coroutine.status(co) == 'suspended' then + return performResume(err, co, coroutine.yield(...)) + else + return true, ... + end +end + +function performResume(err, co, ...) + return handleReturnValue(err, co, coroutine.resume(co, ...)) +end + +function coxpcall(f, err, ...) + local res, co = oldpcall(coroutine.create, f) + if not res then + local params = {...} + local newf = function() return f(unpack(params)) end + co = coroutine.create(newf) + end + local c = coroutine.running() + coxpt[co] = coxpt[c] or c or 0 + return performResume(err, co, ...) +end + +local function id(trace, ...) + return ... +end + +function copcall(f, ...) + return coxpcall(f, id, ...) +end |