aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoramelia squires <[email protected]>2025-10-14 21:46:38 -0500
committeramelia squires <[email protected]>2025-10-14 21:46:38 -0500
commitaf09c42e8067dfc832f7e1dce92860e1022c75fa (patch)
treea444ec4586f9b1c54ea6680ffee2dc940644427d
parenta67dc94484cf9869793fc1861914b800a6559a74 (diff)
tons of thread changed, more testing needed
-rw-r--r--library/lullaby/thread.lua7
-rw-r--r--makefile3
-rw-r--r--src/net.c1
-rw-r--r--src/thread.c60
-rw-r--r--src/thread.h4
-rw-r--r--tests/kill.lua15
-rw-r--r--tests/tests.lua1
7 files changed, 83 insertions, 8 deletions
diff --git a/library/lullaby/thread.lua b/library/lullaby/thread.lua
index 6015a0b..f529049 100644
--- a/library/lullaby/thread.lua
+++ b/library/lullaby/thread.lua
@@ -16,11 +16,16 @@ function async.await(T) end
---@return nil
function async.clean(T) end
----stops the thread
+---stops the thread, may be unavaliable on some systems (android) and will call async:kill instead
---@param T async-table
---@return nil
function async.close(T) end
+---stops the thread forcefully, may cause problems
+---@param T async-table
+---@return nil
+function async.kill(T) end
+
---contains data for the thread
---@deprecated
---@type lightuserdata
diff --git a/makefile b/makefile
index 2e82331..3c69707 100644
--- a/makefile
+++ b/makefile
@@ -57,6 +57,9 @@ debug: all
san: CFLAGS += -ggdb3 -static-libasan -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer -fno-optimize-sibling-calls
san: all
+tsan: CFLAGS += -ggdb3 -static-libasan -fsanitize=undefined -fsanitize=thread -fno-omit-frame-pointer -fno-optimize-sibling-calls
+tsan: all
+
reg:
rm src/reg.o
diff --git a/src/net.c b/src/net.c
index 0abfe04..71168c0 100644
--- a/src/net.c
+++ b/src/net.c
@@ -928,7 +928,6 @@ net_end:
lua_close(L);
threads--;
- printf("out\n");
return NULL;
}
diff --git a/src/thread.c b/src/thread.c
index b113915..da4bcb5 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -3,6 +3,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
+#include <signal.h>
#include "types/str.h"
#include "util.h"
@@ -15,7 +16,7 @@ struct thread_info {
lua_State* L;
int return_count, done;
pthread_t tid;
- pthread_mutex_t* lock;
+ pthread_mutex_t* lock, *ready_lock;
};
#include "io.h"
@@ -168,11 +169,23 @@ int l_res(lua_State* L){
return 1;
}
+void _thread_exit_signal(int i){
+ pthread_exit(NULL);
+}
+
void* handle_thread(void* _args){
struct thread_info* args = (struct thread_info*)_args;
lua_State* L = args->L;
+ pthread_mutex_lock(&*args->lock);
+
+#ifdef SUPPORTS_PTHREAD_CANCEL
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+#endif
+
pthread_detach(args->tid);
+ signal(SIGUSR1, _thread_exit_signal);
+
+ pthread_mutex_unlock(&*args->ready_lock);
lua_newtable(L);
int res_idx = lua_gettop(L);
@@ -202,9 +215,11 @@ int _thread_await(lua_State* L){
lua_pushstring(L, "_");
lua_gettable(L, 1);
struct thread_info* info = lua_touserdata(L, -1);
-
if(info->L == NULL) luaI_error(L, -1, "thread was already closed")
- if(!info->done) pthread_mutex_lock(&*info->lock);
+ //maybe error here if tid is zero
+ if(!info->done && info->tid != 0){
+ pthread_mutex_lock(&*info->lock);
+ }
info->done = 1;
env_table(info->L, 0);
@@ -245,6 +260,14 @@ int _thread_clean(lua_State* L){
if(info != NULL && info->L != NULL){
luaI_tsetnil(L, 1, "_");
+ if(info->tid != 0){
+#ifdef SUPPORTS_PTHREAD_CANCEL
+ pthread_cancel(info->tid);
+#else
+ pthread_kill(info->tid, SIGUSR1);
+#endif
+ }
+
//lua_gc(info->L, LUA_GCRESTART);
lua_gc(info->L, LUA_GCCOLLECT);
@@ -254,18 +277,37 @@ int _thread_clean(lua_State* L){
pthread_mutex_destroy(&*info->lock);
free(info->lock);
- pthread_cancel(info->tid);
+
free(info);
}
return 0;
}
+
int _thread_close(lua_State* L){
+#ifdef SUPPORTS_PTHREAD_CANCEL
+
lua_pushstring(L, "_");
lua_gettable(L, 1);
struct thread_info* info = lua_touserdata(L, -1);
pthread_cancel(info->tid);
+ info->tid = 0;
+
+ return 0;
+#else
+ return _thread_kill(L);
+#endif
+}
+
+
+int _thread_kill(lua_State* L){
+ lua_pushstring(L, "_");
+ lua_gettable(L, 1);
+ struct thread_info* info = lua_touserdata(L, -1);
+
+ pthread_kill(info->tid, SIGUSR1);
+ info->tid = 0;
return 0;
}
@@ -280,20 +322,28 @@ int l_async(lua_State* oL){
struct thread_info* args = calloc(1, sizeof * args);
args->L = L;
args->lock = malloc(sizeof * args->lock);
+ args->ready_lock = malloc(sizeof * args->ready_lock);
pthread_mutex_init(&*args->lock, NULL);
- pthread_mutex_lock(&*args->lock);
+ pthread_mutex_init(&*args->ready_lock, NULL);
args->return_count = 0;
args->function = str_init("");
lua_pushvalue(oL, 1);
lua_dump(oL, writer, (void*)args->function, 0);
+ pthread_mutex_lock(&*args->ready_lock);
pthread_create(&args->tid, NULL, handle_thread, (void*)args);
+ pthread_mutex_lock(&*args->ready_lock);
+
+ pthread_mutex_unlock(&*args->ready_lock);
+ pthread_mutex_destroy(&*args->ready_lock);
+ free(args->ready_lock);
lua_newtable(oL);
int res_idx = lua_gettop(oL);
luaI_tsetcf(oL, res_idx, "await", _thread_await);
luaI_tsetcf(oL, res_idx, "clean", _thread_clean);
+ luaI_tsetcf(oL, res_idx, "kill", _thread_kill);
luaI_tsetcf(oL, res_idx, "close", _thread_close);
luaI_tsetlud(oL, res_idx, "_", args);
diff --git a/src/thread.h b/src/thread.h
index 0b3a27d..4fa0e04 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -1,6 +1,10 @@
#include "lua.h"
#include "config.h"
+#ifndef __ANDROID__
+#define SUPPORTS_PTHREAD_CANCEL
+#endif
+
int l_async(lua_State*);
int l_tlock(lua_State*);
int l_tunlock(lua_State*);
diff --git a/tests/kill.lua b/tests/kill.lua
new file mode 100644
index 0000000..53344dc
--- /dev/null
+++ b/tests/kill.lua
@@ -0,0 +1,15 @@
+local llby = require"lullaby"
+
+local t = llby.thread.async(function(res)
+ for i = 1, 50 do
+ print(i)
+ os.execute("sleep 1")
+ end
+end)
+
+os.execute("sleep 5")
+
+print("killing")
+t:close()
+t:await()
+print("after kill")
diff --git a/tests/tests.lua b/tests/tests.lua
index 6dae570..39c4d12 100644
--- a/tests/tests.lua
+++ b/tests/tests.lua
@@ -20,7 +20,6 @@ end
local handle = assert(io.popen("find tests/units/".. search .." -type f"))
for file in handle:lines() do
- print(_G._locals)
total = total + 1
local f = loadfile(file)()