diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/llthread.c | 37 | ||||
-rw-r--r-- | src/lua/llthreads2/ex.lua | 9 |
2 files changed, 46 insertions, 0 deletions
diff --git a/src/llthread.c b/src/llthread.c index 3155113..66efe7c 100644 --- a/src/llthread.c +++ b/src/llthread.c | |||
@@ -98,11 +98,17 @@ typedef pthread_t os_thread_t; | |||
98 | 98 | ||
99 | #define LLTHREAD_OPEN_NAME LLTHREAD_OPEN_NAME_IMPL(LLTHREAD_MODULE_NAME) | 99 | #define LLTHREAD_OPEN_NAME LLTHREAD_OPEN_NAME_IMPL(LLTHREAD_MODULE_NAME) |
100 | 100 | ||
101 | #define LLTHREAD_STRINGIFY(x) #x | ||
102 | #define LLTHREAD_TOSTRING(x) LLTHREAD_STRINGIFY(x) | ||
103 | #define LLTHREAD_MODULE_NAME_STRING LLTHREAD_TOSTRING(LLTHREAD_MODULE_NAME) | ||
104 | |||
105 | |||
101 | LLTHREADS_EXPORT_API int LLTHREAD_OPEN_NAME(lua_State *L); | 106 | LLTHREADS_EXPORT_API int LLTHREAD_OPEN_NAME(lua_State *L); |
102 | 107 | ||
103 | #define LLTHREAD_NAME "LLThread" | 108 | #define LLTHREAD_NAME "LLThread" |
104 | static const char *LLTHREAD_TAG = LLTHREAD_NAME; | 109 | static const char *LLTHREAD_TAG = LLTHREAD_NAME; |
105 | static const char *LLTHREAD_LOGGER_HOLDER = LLTHREAD_NAME " logger holder"; | 110 | static const char *LLTHREAD_LOGGER_HOLDER = LLTHREAD_NAME " logger holder"; |
111 | static const char* LLTHREAD_INTERRUPTED_ERROR = LLTHREAD_MODULE_NAME_STRING ": thread was interrupted"; | ||
106 | 112 | ||
107 | typedef struct llthread_child_t { | 113 | typedef struct llthread_child_t { |
108 | lua_State *L; | 114 | lua_State *L; |
@@ -694,6 +700,32 @@ static int l_llthread_new(lua_State *L) { | |||
694 | return 1; | 700 | return 1; |
695 | } | 701 | } |
696 | 702 | ||
703 | static void llthread_interrupt1(lua_State *L, lua_Debug *ar) { | ||
704 | (void)ar; /* unused arg. */ | ||
705 | lua_sethook(L, NULL, 0, 0); /* reset hook */ | ||
706 | luaL_error(L, LLTHREAD_INTERRUPTED_ERROR); | ||
707 | } | ||
708 | static void llthread_interrupt2(lua_State *L, lua_Debug *ar) { | ||
709 | (void)ar; /* unused arg. */ | ||
710 | luaL_error(L, LLTHREAD_INTERRUPTED_ERROR); | ||
711 | } | ||
712 | |||
713 | static int l_llthread_interrupt(lua_State *L) { | ||
714 | llthread_t *this = l_llthread_at(L, 1); | ||
715 | llthread_child_t *child = this->child; | ||
716 | lua_Hook hook = llthread_interrupt1; | ||
717 | if (!lua_isnoneornil(L, 2)) | ||
718 | hook = lua_toboolean(L, 2) ? llthread_interrupt2 : NULL; | ||
719 | if (child) { | ||
720 | if (hook) | ||
721 | lua_sethook(child->L, hook, LUA_MASKCALL|LUA_MASKRET|LUA_MASKCOUNT, 1); | ||
722 | else | ||
723 | lua_sethook(child->L, NULL, 0, 0); /* reset hook */ | ||
724 | } | ||
725 | return 0; | ||
726 | } | ||
727 | |||
728 | |||
697 | static const struct luaL_Reg l_llthread_meth[] = { | 729 | static const struct luaL_Reg l_llthread_meth[] = { |
698 | {"start", l_llthread_start }, | 730 | {"start", l_llthread_start }, |
699 | {"join", l_llthread_join }, | 731 | {"join", l_llthread_join }, |
@@ -701,6 +733,7 @@ static const struct luaL_Reg l_llthread_meth[] = { | |||
701 | {"started", l_llthread_started }, | 733 | {"started", l_llthread_started }, |
702 | {"detached", l_llthread_detached }, | 734 | {"detached", l_llthread_detached }, |
703 | {"joinable", l_llthread_joinable }, | 735 | {"joinable", l_llthread_joinable }, |
736 | {"interrupt", l_llthread_interrupt }, | ||
704 | {"__gc", l_llthread_delete }, | 737 | {"__gc", l_llthread_delete }, |
705 | 738 | ||
706 | {NULL, NULL} | 739 | {NULL, NULL} |
@@ -769,5 +802,9 @@ LLTHREADS_EXPORT_API int LLTHREAD_OPEN_NAME(lua_State *L) { | |||
769 | l_llthread_push_version(L); | 802 | l_llthread_push_version(L); |
770 | lua_rawset(L, -3); | 803 | lua_rawset(L, -3); |
771 | 804 | ||
805 | lua_pushliteral(L, "interrupted_error"); | ||
806 | lua_pushstring(L, LLTHREAD_INTERRUPTED_ERROR); | ||
807 | lua_rawset(L, -3); | ||
808 | |||
772 | return 1; | 809 | return 1; |
773 | } | 810 | } |
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() | |||
141 | return self.thread:joinable() | 141 | return self.thread:joinable() |
142 | end | 142 | end |
143 | 143 | ||
144 | --- Interrupt thread | ||
145 | -- The thread is interrupted by installing a debug hook that | ||
146 | -- creates an error. | ||
147 | -- @tparam ?boolean if not given, interrupt only once, | ||
148 | -- otherwise this arg sets or unsets permanent interrupt. | ||
149 | function thread_mt:interrupt(arg) | ||
150 | return self.thread:interrupt(arg) | ||
151 | end | ||
152 | |||
144 | end | 153 | end |
145 | ------------------------------------------------------------------------------- | 154 | ------------------------------------------------------------------------------- |
146 | 155 | ||