Mercurial > prosody-hg
comparison net/server_epoll.lua @ 11761:dbf378dcf27b
net.server_epoll: Prevent removed timers from being readded
In a case like this the timer would not be readded:
addtimer(1, function(t, id)
stop(id)
return 1
end);
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Tue, 31 Aug 2021 13:34:08 +0200 |
| parents | 6427e2642976 |
| children | 9006ff4838ff |
comparison
equal
deleted
inserted
replaced
| 11760:d66738eeb875 | 11761:dbf378dcf27b |
|---|---|
| 97 -- Timer and scheduling -- | 97 -- Timer and scheduling -- |
| 98 | 98 |
| 99 local timers = indexedbheap.create(); | 99 local timers = indexedbheap.create(); |
| 100 | 100 |
| 101 local function noop() end | 101 local function noop() end |
| 102 | |
| 103 -- Keep track of recently closed timers to avoid re-adding them | |
| 104 local closedtimers = {}; | |
| 105 | |
| 102 local function closetimer(id) | 106 local function closetimer(id) |
| 103 timers:remove(id); | 107 if timers:remove(id) then |
| 108 closedtimers[id] = true; | |
| 109 end | |
| 104 end | 110 end |
| 105 | 111 |
| 106 local function reschedule(id, time) | 112 local function reschedule(id, time) |
| 107 time = monotonic() + time; | 113 time = monotonic() + time; |
| 108 timers:reprioritize(id, time); | 114 timers:reprioritize(id, time); |
| 136 break; | 142 break; |
| 137 end | 143 end |
| 138 | 144 |
| 139 local _, timer, id = timers:pop(); | 145 local _, timer, id = timers:pop(); |
| 140 local ok, ret = xpcall(timer, traceback, now, id); | 146 local ok, ret = xpcall(timer, traceback, now, id); |
| 141 if ok and type(ret) == "number" then | 147 if ok and type(ret) == "number" and not closedtimers[id] then |
| 142 local next_time = elapsed+ret; | 148 local next_time = elapsed+ret; |
| 143 -- Delay insertion of timers to be re-added | 149 -- Delay insertion of timers to be re-added |
| 144 -- so they don't get called again this tick | 150 -- so they don't get called again this tick |
| 145 if readd then | 151 if readd then |
| 146 readd[id] = { timer, next_time }; | 152 readd[id] = { timer, next_time }; |
| 157 if readd then | 163 if readd then |
| 158 for id, timer in pairs(readd) do | 164 for id, timer in pairs(readd) do |
| 159 timers:insert(timer[1], timer[2], id); | 165 timers:insert(timer[1], timer[2], id); |
| 160 end | 166 end |
| 161 peek = timers:peek(); | 167 peek = timers:peek(); |
| 168 end | |
| 169 | |
| 170 if next(closedtimers) ~= nil then | |
| 171 closedtimers = {}; | |
| 162 end | 172 end |
| 163 | 173 |
| 164 if peek == nil then | 174 if peek == nil then |
| 165 return next_delay; | 175 return next_delay; |
| 166 else | 176 else |
