Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new method thread:interrupt() #16

Merged
merged 4 commits into from Aug 27, 2018
Merged

new method thread:interrupt() #16

merged 4 commits into from Aug 27, 2018

Conversation

osch
Copy link
Contributor

@osch osch commented Aug 21, 2018

Hi,

here comes a method to interrupt a thread using a debug hook similiar to the SIGINT signal handler of the original lua interpreter (see function laction in lua.c).

Best regards,
Oliver

@moteus
Copy link
Owner

moteus commented Aug 21, 2018

This is not valid access to LuaState from different thread while it executes insepareate thread

@osch
Copy link
Contributor Author

osch commented Aug 21, 2018

But lua_sethook is called from a signal handler in the original lua interpreter and special care has been taken to make the function lua_sethook asynchronously callable, see also the documentation from ldebug.c:

/*
** This function can be called asynchronously (e.g. during a signal).
** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by
** 'resethookcount') are for debug only, and it is no problem if they
** get arbitrary values (causes at most one wrong hook call). 'hookmask'
** is an atomic value. We assume that pointers are atomic too (e.g., gcc
** ensures that for all platforms where it runs). Moreover, 'hook' is
** always checked before being called (see 'luaD_hook').
*/
LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {

@moteus
Copy link
Owner

moteus commented Aug 21, 2018

Did not know that. Thanks.
May be you can also add simple test case.
I think this is how it shold work.

local llthreads = require"llthreads"
local utils     = require "utils"
local sleep     = utils.sleep

local include = utils.thread_init .. [[
local llthreads = require"llthreads"
local sleep = require "utils".sleep
]]

local thread = llthreads.new(include .. [[
  for i = 1, 10 do sleep(1) end
  os.exit(-1)
]])

thread:start()
sleep(1)
thread:interrupt()

local ok, err = thread:join()
print("thread:join(): ", ok, err)
assert(ok, err)
print("Done!")

@osch
Copy link
Contributor Author

osch commented Aug 21, 2018

OK, I will look into the test cases tomorrow.

@osch
Copy link
Contributor Author

osch commented Aug 22, 2018

OK, I added the test cases and they ran successfully on travis and appveyor.

@moteus
Copy link
Owner

moteus commented Aug 27, 2018

Sorry for late response.
I like this feature. I have only one concern.
Error string should be part of public api and i do not like
exclamination mark in it.
Also may be add library name as prefix or at least thread:: prefix?

@osch
Copy link
Contributor Author

osch commented Aug 27, 2018

No problems, I just committed some changes trying to incorporate your wishes: the interrupeted message contains no exclamation mark (btw. the message "interrupted!" is the original message from the lua interpreter, see lstop in lua.c), the message contains now the module name as prefix and is also available in the public api as interrupted_error.

@moteus moteus merged commit 00ca977 into moteus:master Aug 27, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants