moduleapi: in module:provides(), add the name of the module in item._provided_by
[prosody.git] / util / timer.lua
index 4c9a3ea978c3eb07cd36a2853afd4af6d49b6501..af1e57b6d176c487b47c5e2d94e40c4eddb08247 100644 (file)
@@ -1,19 +1,17 @@
 -- Prosody IM
--- Copyright (C) 2008-2009 Matthew Wild
--- Copyright (C) 2008-2009 Waqas Hussain
+-- Copyright (C) 2008-2010 Matthew Wild
+-- Copyright (C) 2008-2010 Waqas Hussain
 -- 
 -- This project is MIT/X11 licensed. Please see the
 -- COPYING file in the source package for more information.
 --
 
-
-local ns_addtimer = require "net.server".addtimer;
-local event = require "net.server".event;
-
-local get_time = os.time;
+local server = require "net.server";
+local math_min = math.min
+local math_huge = math.huge
+local get_time = require "socket".gettime;
 local t_insert = table.insert;
-local t_remove = table.remove;
-local ipairs, pairs = ipairs, pairs;
+local pairs = pairs;
 local type = type;
 
 local data = {};
@@ -22,18 +20,21 @@ local new_data = {};
 module "timer"
 
 local _add_task;
-if not event then
-       function _add_task(delay, func)
+if not server.event then
+       function _add_task(delay, callback)
                local current_time = get_time();
                delay = delay + current_time;
                if delay >= current_time then
-                       t_insert(new_data, {delay, func});
+                       t_insert(new_data, {delay, callback});
                else
-                       func();
+                       local r = callback(current_time);
+                       if r and type(r) == "number" then
+                               return _add_task(r, callback);
+                       end
                end
        end
 
-       ns_addtimer(function()
+       server._addtimer(function()
                local current_time = get_time();
                if #new_data > 0 then
                        for _, d in pairs(new_data) do
@@ -42,23 +43,34 @@ if not event then
                        new_data = {};
                end
                
+               local next_time = math_huge;
                for i, d in pairs(data) do
-                       local t, func = d[1], d[2];
+                       local t, callback = d[1], d[2];
                        if t <= current_time then
                                data[i] = nil;
-                               local r = func(current_time);
-                               if type(r) == "number" then _add_task(r, func); end
+                               local r = callback(current_time);
+                               if type(r) == "number" then
+                                       _add_task(r, callback);
+                                       next_time = math_min(next_time, r);
+                               end
+                       else
+                               next_time = math_min(next_time, t - current_time);
                        end
                end
+               return next_time;
        end);
 else
+       local event = server.event;
+       local event_base = server.event_base;
        local EVENT_LEAVE = (event.core and event.core.LEAVE) or -1;
-       function _add_task(delay, func)
-               event.base:addevent(nil, event.EV_TIMEOUT, function ()
-                       local ret = func();
+
+       function _add_task(delay, callback)
+               local event_handle;
+               event_handle = event_base:addevent(nil, 0, function ()
+                       local ret = callback(get_time());
                        if ret then
-                               _add_task(ret, func);
-                       else
+                               return 0, ret;
+                       elseif event_handle then
                                return EVENT_LEAVE;
                        end
                end