From 535e00626b7e93b32d5a99638d784ede66313cf6 Mon Sep 17 00:00:00 2001 From: osch Date: Tue, 21 Aug 2018 20:44:03 +0200 Subject: new method thread:interrupt() --- src/llthread.c | 27 +++++++++++++++++++++++++++ src/lua/llthreads2/ex.lua | 9 +++++++++ 2 files changed, 36 insertions(+) diff --git a/src/llthread.c b/src/llthread.c index 3155113..c78d766 100644 --- a/src/llthread.c +++ b/src/llthread.c @@ -694,6 +694,32 @@ static int l_llthread_new(lua_State *L) { return 1; } +static void llthread_interrupt1(lua_State *L, lua_Debug *ar) { + (void)ar; /* unused arg. */ + lua_sethook(L, NULL, 0, 0); /* reset hook */ + luaL_error(L, "interrupted!"); +} +static void llthread_interrupt2(lua_State *L, lua_Debug *ar) { + (void)ar; /* unused arg. */ + luaL_error(L, "interrupted!"); +} + +static int l_llthread_interrupt(lua_State *L) { + llthread_t *this = l_llthread_at(L, 1); + llthread_child_t *child = this->child; + lua_Hook hook = llthread_interrupt1; + if (!lua_isnoneornil(L, 2)) + hook = lua_toboolean(L, 2) ? llthread_interrupt2 : NULL; + if (child) { + if (hook) + lua_sethook(child->L, hook, LUA_MASKCALL|LUA_MASKRET|LUA_MASKCOUNT, 1); + else + lua_sethook(child->L, NULL, 0, 0); /* reset hook */ + } + return 0; +} + + static const struct luaL_Reg l_llthread_meth[] = { {"start", l_llthread_start }, {"join", l_llthread_join }, @@ -701,6 +727,7 @@ static const struct luaL_Reg l_llthread_meth[] = { {"started", l_llthread_started }, {"detached", l_llthread_detached }, {"joinable", l_llthread_joinable }, + {"interrupt", l_llthread_interrupt }, {"__gc", l_llthread_delete }, {NULL, NULL} diff --git a/src/lua/llthreads2/ex.lua b/src/lua/llthreads2/ex.lua index f0c27d9..b943f5b 100644 --- a/src/lua/llthreads2/ex.lua +++ b/src/lua/llthreads2/ex.lua @@ -141,6 +141,15 @@ function thread_mt:joinable() return self.thread:joinable() end +--- Interrupt thread +-- The thread is interrupted by installing a debug hook that +-- creates an error. +-- @tparam ?boolean if not given, interrupt only once, +-- otherwise this arg sets or unsets permanent interrupt. +function thread_mt:interrupt(arg) + return self.thread:interrupt(arg) +end + end ------------------------------------------------------------------------------- -- cgit v1.2.3-55-g6feb