From 792398b07ef11702ddc6b842744840969e48b0e6 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Wed, 30 Oct 2013 17:44:42 -0400 Subject: util.timer: Updated to use util.indexedbheap to provide a more complete API. Timers can now be stopped or rescheduled. Callbacks are now pcall'd. Adding/removing timers from within timer callbacks works better. Optional parameter can be passed when creating timer which gets passed to callback, eliminating the need for closures in various timer uses. Timers are now much more lightweight. --- util/timer.lua | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) (limited to 'util/timer.lua') diff --git a/util/timer.lua b/util/timer.lua index 0e10e144..d7a9b0bf 100644 --- a/util/timer.lua +++ b/util/timer.lua @@ -6,6 +6,8 @@ -- COPYING file in the source package for more information. -- +local indexedbheap = require "util.indexedbheap"; +local log = require "util.logger".init("timer"); local server = require "net.server"; local math_min = math.min local math_huge = math.huge @@ -78,6 +80,60 @@ else end end -add_task = _add_task; +--add_task = _add_task; + +local h = indexedbheap.create(); +local params = {}; +local next_time = nil; +local _id, _callback, _now, _param; +local function _call() return _callback(_now, _id, _param); end +local function _traceback_handler(err) log("error", "Traceback[timer]: %s", traceback(tostring(err), 2)); end +local function _on_timer(now) + local peek; + while true do + peek = h:peek(); + if peek == nil or peek > now then break; end + local _; + _, _callback, _id = h:pop(); + _now = now; + _param = params[id]; + params[id] = nil; + --item(now, id, _param); -- FIXME pcall + local success, err = xpcall(_call, _traceback_handler); + if success and type(err) == "number" then + h:insert(_callback, err + now, _id); -- re-add + end + end + next_time = peek; + if peek ~= nil then + return peek - now; + end +end +function add_task(delay, callback, param) + local current_time = get_time(); + local event_time = current_time + delay; + + local id = h:insert(callback, event_time); + params[id] = param; + if next_time == nil or event_time < next_time then + next_time = event_time; + _add_task(next_time - current_time, on_timer); + end + return id; +end +function stop(id) + params[id] = nil; + return h:remove(id); +end +function reschedule(id, delay) + local current_time = get_time(); + local event_time = current_time + delay; + h:reprioritize(id, delay); + if next_time == nil or event_time < next_time then + next_time = event_time; + _add_task(next_time - current_time, on_timer); + end + return id; +end return _M; -- cgit v1.2.3 From 0f260f9b4e23572e8063c0e4302ca9bccac117d0 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Wed, 30 Oct 2013 17:51:37 -0400 Subject: util.timer: Fix variable name typo. --- util/timer.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'util/timer.lua') diff --git a/util/timer.lua b/util/timer.lua index d7a9b0bf..99aade15 100644 --- a/util/timer.lua +++ b/util/timer.lua @@ -117,7 +117,7 @@ function add_task(delay, callback, param) params[id] = param; if next_time == nil or event_time < next_time then next_time = event_time; - _add_task(next_time - current_time, on_timer); + _add_task(next_time - current_time, _on_timer); end return id; end @@ -131,7 +131,7 @@ function reschedule(id, delay) h:reprioritize(id, delay); if next_time == nil or event_time < next_time then next_time = event_time; - _add_task(next_time - current_time, on_timer); + _add_task(next_time - current_time, _on_timer); end return id; end -- cgit v1.2.3 From ad2211ad5722c3f1e46587682eaa85210321a68d Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Wed, 30 Oct 2013 17:56:00 -0400 Subject: util.timer: Fix another variable name typo (thanks again zash). --- util/timer.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'util/timer.lua') diff --git a/util/timer.lua b/util/timer.lua index 99aade15..76deaff1 100644 --- a/util/timer.lua +++ b/util/timer.lua @@ -96,8 +96,8 @@ local function _on_timer(now) local _; _, _callback, _id = h:pop(); _now = now; - _param = params[id]; - params[id] = nil; + _param = params[_id]; + params[_id] = nil; --item(now, id, _param); -- FIXME pcall local success, err = xpcall(_call, _traceback_handler); if success and type(err) == "number" then -- cgit v1.2.3 From 9fde274e2174f63d3f50e38f2992b6019a106ec7 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Wed, 30 Oct 2013 17:58:17 -0400 Subject: util.timer: Import all require upvalues. --- util/timer.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'util/timer.lua') diff --git a/util/timer.lua b/util/timer.lua index 76deaff1..451e27d3 100644 --- a/util/timer.lua +++ b/util/timer.lua @@ -15,6 +15,9 @@ local get_time = require "socket".gettime; local t_insert = table.insert; local pairs = pairs; local type = type; +local debug_traceback = debug.traceback; +local tostring = tostring; +local xpcall = xpcall; local data = {}; local new_data = {}; @@ -87,7 +90,7 @@ local params = {}; local next_time = nil; local _id, _callback, _now, _param; local function _call() return _callback(_now, _id, _param); end -local function _traceback_handler(err) log("error", "Traceback[timer]: %s", traceback(tostring(err), 2)); end +local function _traceback_handler(err) log("error", "Traceback[timer]: %s", debug_traceback(tostring(err), 2)); end local function _on_timer(now) local peek; while true do -- cgit v1.2.3 From b3325a4073f83da672df19711e78be2d58c7ff92 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 6 Nov 2013 12:56:18 -0500 Subject: util/timer: Re-set params when timer is rescheduled --- util/timer.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'util/timer.lua') diff --git a/util/timer.lua b/util/timer.lua index 451e27d3..23bd6a37 100644 --- a/util/timer.lua +++ b/util/timer.lua @@ -105,6 +105,7 @@ local function _on_timer(now) local success, err = xpcall(_call, _traceback_handler); if success and type(err) == "number" then h:insert(_callback, err + now, _id); -- re-add + params[_id] = _param; end end next_time = peek; -- cgit v1.2.3