/opt/imunify360-webshield/lualib/resty
-- Copyright (C) Yichun Zhang (agentzh) require "resty.core.shdict" -- enforce this to avoid dead locks local ffi = require "ffi" local ffi_new = ffi.new local shared = ngx.shared local sleep = ngx.sleep local log = ngx.log local max = math.max local min = math.min local debug = ngx.config.debug local setmetatable = setmetatable local tonumber = tonumber local _M = { _VERSION = '0.08' } local mt = { __index = _M } local ERR = ngx.ERR local FREE_LIST_REF = 0 -- FIXME: we don't need this when we have __gc metamethod support on Lua -- tables. local memo = {} if debug then _M.memo = memo end local function ref_obj(key) if key == nil then return -1 end local ref = memo[FREE_LIST_REF] if ref and ref ~= 0 then memo[FREE_LIST_REF] = memo[ref] else ref = #memo + 1 end memo[ref] = key -- print("ref key_id returned ", ref) return ref end if debug then _M.ref_obj = ref_obj end local function unref_obj(ref) if ref >= 0 then memo[ref] = memo[FREE_LIST_REF] memo[FREE_LIST_REF] = ref end end if debug then _M.unref_obj = unref_obj end local function gc_lock(cdata) local dict_id = tonumber(cdata.dict_id) local key_id = tonumber(cdata.key_id) -- print("key_id: ", key_id, ", key: ", memo[key_id], "dict: ", -- type(memo[cdata.dict_id])) if key_id > 0 then local key = memo[key_id] unref_obj(key_id) local dict = memo[dict_id] -- print("dict.delete type: ", type(dict.delete)) local ok, err = dict:delete(key) if not ok then log(ERR, 'failed to delete key "', key, '": ', err) end cdata.key_id = 0 end unref_obj(dict_id) end local ctype = ffi.metatype("struct { int key_id; int dict_id; }", { __gc = gc_lock }) function _M.new(_, dict_name, opts) local dict = shared[dict_name] if not dict then return nil, "dictionary not found" end local cdata = ffi_new(ctype) cdata.key_id = 0 cdata.dict_id = ref_obj(dict) local timeout, exptime, step, ratio, max_step if opts then timeout = opts.timeout exptime = opts.exptime step = opts.step ratio = opts.ratio max_step = opts.max_step end if not exptime then exptime = 30 end if timeout then timeout = min(timeout, exptime) if step then step = min(step, timeout) end end local self = { cdata = cdata, dict = dict, timeout = timeout or 5, exptime = exptime, step = step or 0.001, ratio = ratio or 2, max_step = max_step or 0.5, } setmetatable(self, mt) return self end function _M.lock(self, key) if not key then return nil, "nil key" end local dict = self.dict local cdata = self.cdata if cdata.key_id > 0 then return nil, "locked" end local exptime = self.exptime local ok, err = dict:add(key, true, exptime) if ok then cdata.key_id = ref_obj(key) self.key = key return 0 end if err ~= "exists" then return nil, err end -- lock held by others local step = self.step local ratio = self.ratio local timeout = self.timeout local max_step = self.max_step local elapsed = 0 while timeout > 0 do sleep(step) elapsed = elapsed + step timeout = timeout - step local ok, err = dict:add(key, true, exptime) if ok then cdata.key_id = ref_obj(key) self.key = key return elapsed end if err ~= "exists" then return nil, err end if timeout <= 0 then break end step = min(max(0.001, step * ratio), timeout, max_step) end return nil, "timeout" end function _M.unlock(self) local dict = self.dict local cdata = self.cdata local key_id = tonumber(cdata.key_id) if key_id <= 0 then return nil, "unlocked" end local key = memo[key_id] unref_obj(key_id) local ok, err = dict:delete(key) if not ok then return nil, err end cdata.key_id = 0 return 1 end function _M.expire(self, time) local dict = self.dict local cdata = self.cdata local key_id = tonumber(cdata.key_id) if key_id <= 0 then return nil, "unlocked" end if not time then time = self.exptime end local ok, err = dict:replace(self.key, true, time) if not ok then return nil, err end return true end return _M
.
Edit
..
Edit
aes.lua
Edit
cookie.lua
Edit
core
Edit
core.lua
Edit
dns
Edit
http.lua
Edit
http_headers.lua
Edit
limit
Edit
lock.lua
Edit
lrucache
Edit
lrucache.lua
Edit
md5.lua
Edit
random.lua
Edit
sha.lua
Edit
sha1.lua
Edit
sha224.lua
Edit
sha256.lua
Edit
sha384.lua
Edit
sha512.lua
Edit
shell.lua
Edit
signal.lua
Edit
string.lua
Edit
template
Edit
template.lua
Edit
upstream
Edit
websocket
Edit