Software /
code /
prosody
Comparison
util/timer.lua @ 5877:615a0774e4cc
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.
author | Waqas Hussain <waqas20@gmail.com> |
---|---|
date | Wed, 30 Oct 2013 17:44:42 -0400 |
parent | 5776:bd0ff8ae98a8 |
child | 5878:2b1c0c0a2ea6 |
comparison
equal
deleted
inserted
replaced
5876:f62ad84811df | 5877:615a0774e4cc |
---|---|
4 -- | 4 -- |
5 -- This project is MIT/X11 licensed. Please see the | 5 -- This project is MIT/X11 licensed. Please see the |
6 -- COPYING file in the source package for more information. | 6 -- COPYING file in the source package for more information. |
7 -- | 7 -- |
8 | 8 |
9 local indexedbheap = require "util.indexedbheap"; | |
10 local log = require "util.logger".init("timer"); | |
9 local server = require "net.server"; | 11 local server = require "net.server"; |
10 local math_min = math.min | 12 local math_min = math.min |
11 local math_huge = math.huge | 13 local math_huge = math.huge |
12 local get_time = require "socket".gettime; | 14 local get_time = require "socket".gettime; |
13 local t_insert = table.insert; | 15 local t_insert = table.insert; |
76 end | 78 end |
77 , delay); | 79 , delay); |
78 end | 80 end |
79 end | 81 end |
80 | 82 |
81 add_task = _add_task; | 83 --add_task = _add_task; |
84 | |
85 local h = indexedbheap.create(); | |
86 local params = {}; | |
87 local next_time = nil; | |
88 local _id, _callback, _now, _param; | |
89 local function _call() return _callback(_now, _id, _param); end | |
90 local function _traceback_handler(err) log("error", "Traceback[timer]: %s", traceback(tostring(err), 2)); end | |
91 local function _on_timer(now) | |
92 local peek; | |
93 while true do | |
94 peek = h:peek(); | |
95 if peek == nil or peek > now then break; end | |
96 local _; | |
97 _, _callback, _id = h:pop(); | |
98 _now = now; | |
99 _param = params[id]; | |
100 params[id] = nil; | |
101 --item(now, id, _param); -- FIXME pcall | |
102 local success, err = xpcall(_call, _traceback_handler); | |
103 if success and type(err) == "number" then | |
104 h:insert(_callback, err + now, _id); -- re-add | |
105 end | |
106 end | |
107 next_time = peek; | |
108 if peek ~= nil then | |
109 return peek - now; | |
110 end | |
111 end | |
112 function add_task(delay, callback, param) | |
113 local current_time = get_time(); | |
114 local event_time = current_time + delay; | |
115 | |
116 local id = h:insert(callback, event_time); | |
117 params[id] = param; | |
118 if next_time == nil or event_time < next_time then | |
119 next_time = event_time; | |
120 _add_task(next_time - current_time, on_timer); | |
121 end | |
122 return id; | |
123 end | |
124 function stop(id) | |
125 params[id] = nil; | |
126 return h:remove(id); | |
127 end | |
128 function reschedule(id, delay) | |
129 local current_time = get_time(); | |
130 local event_time = current_time + delay; | |
131 h:reprioritize(id, delay); | |
132 if next_time == nil or event_time < next_time then | |
133 next_time = event_time; | |
134 _add_task(next_time - current_time, on_timer); | |
135 end | |
136 return id; | |
137 end | |
82 | 138 |
83 return _M; | 139 return _M; |