Merge with backout
[prosody.git] / util / timer.lua
1 -- Prosody IM
2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 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                 local event_handle;
59                 event_handle = event_base:addevent(nil, 0, function ()
60                         local ret = func();
61                         if ret then
62                                 return 0, ret;
63                         elseif event_handle then
64                                 return EVENT_LEAVE;
65                         end
66                 end
67                 , delay);
68         end
69 end
70
71 add_task = _add_task;
72
73 return _M;