Merge with tip.
[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 local event_base = require "net.server".event_base;
13
14 local get_time = os.time;
15 local t_insert = table.insert;
16 local t_remove = table.remove;
17 local ipairs, pairs = ipairs, pairs;
18 local type = type;
19
20 local data = {};
21 local new_data = {};
22
23 module "timer"
24
25 local _add_task;
26 if not event then
27         function _add_task(delay, func)
28                 local current_time = get_time();
29                 delay = delay + current_time;
30                 if delay >= current_time then
31                         t_insert(new_data, {delay, func});
32                 else
33                         func();
34                 end
35         end
36
37         ns_addtimer(function()
38                 local current_time = get_time();
39                 if #new_data > 0 then
40                         for _, d in pairs(new_data) do
41                                 t_insert(data, d);
42                         end
43                         new_data = {};
44                 end
45                 
46                 for i, d in pairs(data) do
47                         local t, func = d[1], d[2];
48                         if t <= current_time then
49                                 data[i] = nil;
50                                 local r = func(current_time);
51                                 if type(r) == "number" then _add_task(r, func); end
52                         end
53                 end
54         end);
55 else
56         local EVENT_LEAVE = (event.core and event.core.LEAVE) or -1;
57         function _add_task(delay, func)
58                 event_base:addevent(nil, event.EV_TIMEOUT, function ()
59                         local ret = func();
60                         if ret then
61                                 _add_task(ret, func);
62                         else
63                                 return EVENT_LEAVE;
64                         end
65                 end
66                 , delay);
67         end
68 end
69
70 add_task = _add_task;
71
72 return _M;