util.timer: Use libevent for lightweight timers if available and configured (use_libe...
[prosody.git] / util / timer.lua
1 -- Prosody IM
2 -- Copyright (C) 2008-2009 Matthew Wild
3 -- Copyright (C) 2008-2009 Waqas Hussain
4 -- 
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
7 --
8
9
10 local ns_addtimer = require "net.server".addtimer;
11 local event = require "net.server".event;
12
13 local get_time = os.time;
14 local t_insert = table.insert;
15 local t_remove = table.remove;
16 local ipairs, pairs = ipairs, pairs;
17 local type = type;
18
19 local data = {};
20 local new_data = {};
21
22 module "timer"
23
24 local _add_task;
25 if not event then
26         function _add_task(delay, func)
27                 local current_time = get_time();
28                 delay = delay + current_time;
29                 if delay >= current_time then
30                         t_insert(new_data, {delay, func});
31                 else
32                         func();
33                 end
34         end
35
36         ns_addtimer(function()
37                 local current_time = get_time();
38                 if #new_data > 0 then
39                         for _, d in pairs(new_data) do
40                                 t_insert(data, d);
41                         end
42                         new_data = {};
43                 end
44                 
45                 for i, d in pairs(data) do
46                         local t, func = d[1], d[2];
47                         if t <= current_time then
48                                 data[i] = nil;
49                                 local r = func(current_time);
50                                 if type(r) == "number" then _add_task(r, func); end
51                         end
52                 end
53         end);
54 else
55         local EVENT_LEAVE = (event.core and event.core.LEAVE) or -1;
56         function _add_task(delay, func)
57                 event.base:addevent(nil, event.EV_TIMEOUT, function ()
58                         local ret = func();
59                         if ret then
60                                 _add_task(ret, func);
61                         else
62                                 return EVENT_LEAVE;
63                         end
64                 end
65                 , delay);
66         end
67 end
68
69 add_task = _add_task;
70
71 return _M;