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 |