Software /
code /
prosody
Comparison
net/server_epoll.lua @ 11262:2c559953ad41 0.11
net.server_epoll: Ensure timers can't run more than once per tick
This makes sure that a timer that returns 0 (or less) does not prevent
runtimers() from completing, as well as making sure a timer added with
zero timeout from within a timer does not run until the next tick.
Thanks tmolitor
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 08 Jan 2021 21:57:19 +0100 |
parent | 11063:30d3f6f85eb8 |
child | 11264:2cdcf55c6dd5 |
child | 11265:957d417eb56e |
comparison
equal
deleted
inserted
replaced
11261:be38ae8fdfa5 | 11262:2c559953ad41 |
---|---|
95 -- Return time until next timeout | 95 -- Return time until next timeout |
96 local function runtimers(next_delay, min_wait) | 96 local function runtimers(next_delay, min_wait) |
97 -- Any timers at all? | 97 -- Any timers at all? |
98 local now = gettime(); | 98 local now = gettime(); |
99 local peek = timers:peek(); | 99 local peek = timers:peek(); |
100 local readd; | |
100 while peek do | 101 while peek do |
101 | 102 |
102 if peek > now then | 103 if peek > now then |
103 next_delay = peek - now; | |
104 break; | 104 break; |
105 end | 105 end |
106 | 106 |
107 local _, timer, id = timers:pop(); | 107 local _, timer, id = timers:pop(); |
108 local ok, ret = pcall(timer[2], now); | 108 local ok, ret = pcall(timer[2], now); |
109 if ok and type(ret) == "number" then | 109 if ok and type(ret) == "number" then |
110 local next_time = now+ret; | 110 local next_time = now+ret; |
111 timer[1] = next_time; | 111 timer[1] = next_time; |
112 timers:insert(timer, next_time); | 112 -- Delay insertion of timers to be re-added |
113 -- so they don't get called again this tick | |
114 if readd then | |
115 readd[id] = timer; | |
116 else | |
117 readd = { [id] = timer }; | |
118 end | |
113 end | 119 end |
114 | 120 |
115 peek = timers:peek(); | 121 peek = timers:peek(); |
116 end | 122 end |
123 | |
124 if readd then | |
125 for _, timer in pairs(readd) do | |
126 timers:insert(timer, timer[2]); | |
127 end | |
128 peek = timers:peek(); | |
129 end | |
130 | |
117 if peek == nil then | 131 if peek == nil then |
118 return next_delay; | 132 return next_delay; |
133 else | |
134 next_delay = peek - now; | |
119 end | 135 end |
120 | 136 |
121 if next_delay < min_wait then | 137 if next_delay < min_wait then |
122 return min_wait; | 138 return min_wait; |
123 end | 139 end |