util/timer.lua
author Matthew Wild <mwild1@gmail.com>
Fri, 09 Mar 2012 18:46:19 +0000
changeset 4518 f2d695d2e31e
parent 4413 ffa4bed1b716
child 4751 0c7ae4bfc835
permissions -rw-r--r--
Merge 0.9->trunk
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1523
841d61be198f Remove version number from copyright headers
Matthew Wild <mwild1@gmail.com>
parents: 896
diff changeset
     1
-- Prosody IM
2923
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
     2
-- Copyright (C) 2008-2010 Matthew Wild
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
     3
-- Copyright (C) 2008-2010 Waqas Hussain
832
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     4
-- 
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     5
-- This project is MIT/X11 licensed. Please see the
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     6
-- COPYING file in the source package for more information.
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     7
--
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     8
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     9
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    10
local ns_addtimer = require "net.server".addtimer;
2095
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    11
local event = require "net.server".event;
2098
a1ad06f1c090 util.timer: Fix libevent timers (event.base doesn't exist...)
Matthew Wild <mwild1@gmail.com>
parents: 2095
diff changeset
    12
local event_base = require "net.server".event_base;
2095
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    13
3683
c2158221e2e6 util.timer: Activate higher timer precision.
Waqas Hussain <waqas20@gmail.com>
parents: 2964
diff changeset
    14
local math_min = math.min
c2158221e2e6 util.timer: Activate higher timer precision.
Waqas Hussain <waqas20@gmail.com>
parents: 2964
diff changeset
    15
local math_huge = math.huge
c2158221e2e6 util.timer: Activate higher timer precision.
Waqas Hussain <waqas20@gmail.com>
parents: 2964
diff changeset
    16
local get_time = require "socket".gettime;
832
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    17
local t_insert = table.insert;
841
77ff000c2055 util.timer: Fix crash when loaded but no tasks set, fix skipping some tasks when multiple set, and one removed
Matthew Wild <mwild1@gmail.com>
parents: 832
diff changeset
    18
local t_remove = table.remove;
77ff000c2055 util.timer: Fix crash when loaded but no tasks set, fix skipping some tasks when multiple set, and one removed
Matthew Wild <mwild1@gmail.com>
parents: 832
diff changeset
    19
local ipairs, pairs = ipairs, pairs;
832
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    20
local type = type;
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    21
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    22
local data = {};
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    23
local new_data = {};
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    24
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    25
module "timer"
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    26
2095
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    27
local _add_task;
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    28
if not event then
4413
ffa4bed1b716 util.timer: Variable name change (func -> callback)
Matthew Wild <mwild1@gmail.com>
parents: 4385
diff changeset
    29
	function _add_task(delay, callback)
2095
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    30
		local current_time = get_time();
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    31
		delay = delay + current_time;
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    32
		if delay >= current_time then
4413
ffa4bed1b716 util.timer: Variable name change (func -> callback)
Matthew Wild <mwild1@gmail.com>
parents: 4385
diff changeset
    33
			t_insert(new_data, {delay, callback});
2095
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    34
		else
4413
ffa4bed1b716 util.timer: Variable name change (func -> callback)
Matthew Wild <mwild1@gmail.com>
parents: 4385
diff changeset
    35
			local r = callback();
4385
c94167139f27 util.timer: Fix corner case of timer not repeating if it returns <= 0
Matthew Wild <mwild1@gmail.com>
parents: 3683
diff changeset
    36
			if r and type(r) == "number" then
4413
ffa4bed1b716 util.timer: Variable name change (func -> callback)
Matthew Wild <mwild1@gmail.com>
parents: 4385
diff changeset
    37
				return _add_task(r, callback);
4385
c94167139f27 util.timer: Fix corner case of timer not repeating if it returns <= 0
Matthew Wild <mwild1@gmail.com>
parents: 3683
diff changeset
    38
			end
2095
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    39
		end
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    40
	end
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    41
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    42
	ns_addtimer(function()
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    43
		local current_time = get_time();
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    44
		if #new_data > 0 then
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    45
			for _, d in pairs(new_data) do
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    46
				t_insert(data, d);
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    47
			end
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    48
			new_data = {};
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    49
		end
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    50
		
3683
c2158221e2e6 util.timer: Activate higher timer precision.
Waqas Hussain <waqas20@gmail.com>
parents: 2964
diff changeset
    51
		local next_time = math_huge;
2095
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    52
		for i, d in pairs(data) do
4413
ffa4bed1b716 util.timer: Variable name change (func -> callback)
Matthew Wild <mwild1@gmail.com>
parents: 4385
diff changeset
    53
			local t, callback = d[1], d[2];
2095
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    54
			if t <= current_time then
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    55
				data[i] = nil;
4413
ffa4bed1b716 util.timer: Variable name change (func -> callback)
Matthew Wild <mwild1@gmail.com>
parents: 4385
diff changeset
    56
				local r = callback(current_time);
3683
c2158221e2e6 util.timer: Activate higher timer precision.
Waqas Hussain <waqas20@gmail.com>
parents: 2964
diff changeset
    57
				if type(r) == "number" then
4413
ffa4bed1b716 util.timer: Variable name change (func -> callback)
Matthew Wild <mwild1@gmail.com>
parents: 4385
diff changeset
    58
					_add_task(r, callback);
3683
c2158221e2e6 util.timer: Activate higher timer precision.
Waqas Hussain <waqas20@gmail.com>
parents: 2964
diff changeset
    59
					next_time = math_min(next_time, r);
c2158221e2e6 util.timer: Activate higher timer precision.
Waqas Hussain <waqas20@gmail.com>
parents: 2964
diff changeset
    60
				end
c2158221e2e6 util.timer: Activate higher timer precision.
Waqas Hussain <waqas20@gmail.com>
parents: 2964
diff changeset
    61
			else
c2158221e2e6 util.timer: Activate higher timer precision.
Waqas Hussain <waqas20@gmail.com>
parents: 2964
diff changeset
    62
				next_time = math_min(next_time, t - current_time);
2095
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    63
			end
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    64
		end
3683
c2158221e2e6 util.timer: Activate higher timer precision.
Waqas Hussain <waqas20@gmail.com>
parents: 2964
diff changeset
    65
		return next_time;
2095
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    66
	end);
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    67
else
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    68
	local EVENT_LEAVE = (event.core and event.core.LEAVE) or -1;
4413
ffa4bed1b716 util.timer: Variable name change (func -> callback)
Matthew Wild <mwild1@gmail.com>
parents: 4385
diff changeset
    69
	function _add_task(delay, callback)
2964
49b5c87d2fa0 util.timer: When using libevent hold onto the event handle to stop it being collected (and the timer stopping). Fixes BOSH ghosts, thanks Flo, niekie, waqas.
Matthew Wild <mwild1@gmail.com>
parents: 2925
diff changeset
    70
		local event_handle;
49b5c87d2fa0 util.timer: When using libevent hold onto the event handle to stop it being collected (and the timer stopping). Fixes BOSH ghosts, thanks Flo, niekie, waqas.
Matthew Wild <mwild1@gmail.com>
parents: 2925
diff changeset
    71
		event_handle = event_base:addevent(nil, 0, function ()
4413
ffa4bed1b716 util.timer: Variable name change (func -> callback)
Matthew Wild <mwild1@gmail.com>
parents: 4385
diff changeset
    72
			local ret = callback();
2095
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    73
			if ret then
2366
c3a364342cb4 util.timer: Use luaevent's built-in method of repeating an event (fixes a weird crash)
Matthew Wild <mwild1@gmail.com>
parents: 2098
diff changeset
    74
				return 0, ret;
2964
49b5c87d2fa0 util.timer: When using libevent hold onto the event handle to stop it being collected (and the timer stopping). Fixes BOSH ghosts, thanks Flo, niekie, waqas.
Matthew Wild <mwild1@gmail.com>
parents: 2925
diff changeset
    75
			elseif event_handle then
2095
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    76
				return EVENT_LEAVE;
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    77
			end
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    78
		end
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    79
		, delay);
3256c5d00901 util.timer: Use libevent for lightweight timers if available and configured (use_libevent option)
Matthew Wild <mwild1@gmail.com>
parents: 1871
diff changeset
    80
	end
832
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    81
end
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    82
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    83
add_task = _add_task;
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    84
282ae70db19f Added util/timer.lua - a timer API
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    85
return _M;