Mercurial > prosody-hg
comparison util/async.lua @ 8609:9f6ab206d741
util.async: Ensure runner is left in correct state after out-of-main-loop error (+tests)
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Fri, 16 Mar 2018 22:26:15 +0000 |
| parents | 1c8c7fd259c8 |
| children | b03c7884fade |
comparison
equal
deleted
inserted
replaced
| 8608:a2e6caf5848d | 8609:9f6ab206d741 |
|---|---|
| 15 log("warn", "unexpected async state: thread not suspended"); | 15 log("warn", "unexpected async state: thread not suspended"); |
| 16 return false; | 16 return false; |
| 17 end | 17 end |
| 18 local ok, state, runner = coroutine.resume(thread); | 18 local ok, state, runner = coroutine.resume(thread); |
| 19 if not ok then | 19 if not ok then |
| 20 local err = state; | |
| 20 -- Running the coroutine failed, which means we have to find the runner manually, | 21 -- Running the coroutine failed, which means we have to find the runner manually, |
| 21 -- in order to inform the error handler | 22 -- in order to inform the error handler |
| 22 local level = 0; | 23 local level = 0; |
| 23 while debug.getinfo(thread, level, "") do level = level + 1; end | 24 while debug.getinfo(thread, level, "") do level = level + 1; end |
| 24 ok, runner = debug.getlocal(thread, level-1, 1); | 25 ok, runner = debug.getlocal(thread, level-1, 1); |
| 25 local error_handler = runner.watchers.error; | 26 local error_handler = runner.watchers.error; |
| 26 if error_handler then error_handler(runner, debug.traceback(thread, state)); end | 27 if error_handler then error_handler(runner, debug.traceback(thread, err)); end |
| 28 local ready_handler = runner.watchers.ready; | |
| 29 runner.state, runner.thread = "ready", nil; | |
| 30 if ready_handler then ready_handler(runner); end | |
| 31 runner.notified_state = "ready"; | |
| 27 elseif state == "ready" then | 32 elseif state == "ready" then |
| 28 -- If state is 'ready', it is our responsibility to update runner.state from 'waiting'. | 33 -- If state is 'ready', it is our responsibility to update runner.state from 'waiting'. |
| 29 -- We also have to :run(), because the queue might have further items that will not be | 34 -- We also have to :run(), because the queue might have further items that will not be |
| 30 -- processed otherwise. FIXME: It's probably best to do this in a nexttick (0 timer). | 35 -- processed otherwise. FIXME: It's probably best to do this in a nexttick (0 timer). |
| 31 runner.state = "ready"; | 36 runner.state = "ready"; |
