diff options
| author | amelia squires <[email protected]> | 2025-10-17 03:01:20 -0500 |
|---|---|---|
| committer | amelia squires <[email protected]> | 2025-10-17 03:01:20 -0500 |
| commit | 9f42df734f58c805f153afedd87a5bb720618ada (patch) | |
| tree | 46349e78b832cf24c37067e6566fb0660b30d636 | |
| parent | b94f6d148193f91cab50d16e2873095827b89b1b (diff) | |
thread saftey
| -rw-r--r-- | docs/common.md | 22 | ||||
| -rw-r--r-- | docs/crypto.md | 2 | ||||
| -rw-r--r-- | docs/io.md | 2 | ||||
| -rw-r--r-- | docs/math.md | 2 | ||||
| -rw-r--r-- | docs/readme.md | 16 | ||||
| -rw-r--r-- | docs/table.md | 2 | ||||
| -rw-r--r-- | docs/thread.md | 2 | ||||
| -rw-r--r-- | library/lullaby/thread.lua | 2 | ||||
| -rw-r--r-- | src/thread.c | 34 | ||||
| -rw-r--r-- | tests/kill.lua | 4 |
10 files changed, 53 insertions, 35 deletions
diff --git a/docs/common.md b/docs/common.md deleted file mode 100644 index c0d5be7..0000000 --- a/docs/common.md +++ /dev/null @@ -1,22 +0,0 @@ -## errors - -errors will typically be created and propogated using luaI_error (in c) but will always retain a common style (unless mentioned otherwise) - -it will return 3 values, in order - -* nil (just always a nil value first, useful to do a quick check for errors on functions with a return value) -* string (an error message) -* integer (an error code) - -similarily, when luaI_assert is called, the string will be the expression and the integer will be -1 - -## stream - -this is a generic function used in many places. - -stream:read(?bytes) -stream:file(filename, ?bytes, ?mode) - -bytes is an optional value allowing you to select how many bytes at maximum to read. this value can be ignored or adjusted by the function, and if so, it will be noted in the docs (default is nil, and will read as much as possible) - -mode is the mode the file will be opened with (defaults to "w") diff --git a/docs/crypto.md b/docs/crypto.md index c55e6ed..9f785af 100644 --- a/docs/crypto.md +++ b/docs/crypto.md @@ -1,5 +1,7 @@ # crypto +> out of date! + ## hashing \* is optional @@ -1,5 +1,7 @@ # io +> out of date!! + ## common ### pprint diff --git a/docs/math.md b/docs/math.md index 0a84a8a..4bc1743 100644 --- a/docs/math.md +++ b/docs/math.md @@ -1,5 +1,7 @@ # math +> out of date!! + ## common ### lcm diff --git a/docs/readme.md b/docs/readme.md index 9436ba0..83c02e5 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -1,4 +1,7 @@ # lullaby (llby)
+
+> all files besides this and the content of net/ are out of date! ill be working on them later
+
(name subject to change)
with the library in the same directory [(or one of the other valid search locations)](https://www.lua.org/pil/8.1.html)
@@ -49,6 +52,19 @@ the number of bytes can be selected, the function will return an amount close to some streams may not support the bytes param, and may just ignore it. if it is ignored or not given it will always read the entire stream
+### errors
+
+errors will typically be created and propogated using luaI_error (in c) but will always retain a common style (unless mentioned otherwise)
+
+it will return 3 values, in order
+
+* nil (just always a nil value first, useful to do a quick check for errors on functions with a return value)
+* string (an error message)
+* integer (an error code)
+
+similarily, when luaI_assert is called, the string will be the expression and the integer will be -1
+
+
---
## big changes
diff --git a/docs/table.md b/docs/table.md index e58dd54..9e23332 100644 --- a/docs/table.md +++ b/docs/table.md @@ -1,5 +1,7 @@ # table (tables and sorting) +> out of date!! + ## sorting |name|accepted types|type of sorting|order| diff --git a/docs/thread.md b/docs/thread.md index 62e31bf..aff9aab 100644 --- a/docs/thread.md +++ b/docs/thread.md @@ -1,5 +1,7 @@ # threads **
+> out of date!!
+
## buffer
'takes 'anything'
diff --git a/library/lullaby/thread.lua b/library/lullaby/thread.lua index f529049..ca0f1be 100644 --- a/library/lullaby/thread.lua +++ b/library/lullaby/thread.lua @@ -21,7 +21,7 @@ function async.clean(T) end ---@return nil function async.close(T) end ----stops the thread forcefully, may cause problems +---stops the thread forcefully, may cause problems, likely not thread-safe ---@param T async-table ---@return nil function async.kill(T) end diff --git a/src/thread.c b/src/thread.c index bb18ad3..1964ad6 100644 --- a/src/thread.c +++ b/src/thread.c @@ -4,6 +4,7 @@ #include <unistd.h>
#include <pthread.h>
#include <signal.h>
+#include <sys/eventfd.h>
#include "types/str.h"
#include "util.h"
@@ -17,6 +18,7 @@ struct thread_info { int return_count, done;
pthread_t tid;
pthread_mutex_t* lock, *ready_lock;
+ pthread_cond_t* cond;
};
#include "io.h"
@@ -182,9 +184,12 @@ void* handle_thread(void* _args){ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
#endif
- pthread_detach(args->tid);
signal(SIGUSR1, _thread_exit_signal);
+ pthread_detach(args->tid);
+ //unlock main
+ pthread_mutex_lock(&*args->ready_lock);
+ pthread_cond_signal(&*args->cond);
pthread_mutex_unlock(&*args->ready_lock);
lua_newtable(L);
@@ -205,7 +210,7 @@ void* handle_thread(void* _args){ lua_assign_upvalues(L, x);
lua_pushvalue(L, res_idx);
lua_call(L, 1, 0);
- args->tid = 0;
+ args->done = 1;
pthread_mutex_unlock(&*args->lock);
return NULL;
@@ -216,11 +221,10 @@ int _thread_await(lua_State* 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->tid == 0) luaI_error(L, -2, "thread was killed early")
+
//maybe error here if tid is zero
- if(!info->done && info->tid != 0){
- pthread_mutex_lock(&*info->lock);
- }
- info->done = 1;
+ pthread_mutex_lock(&*info->lock);
env_table(info->L, 0);
luaI_deepcopy(info->L, L, SKIP_LOCALS);
@@ -249,6 +253,7 @@ int _thread_await(lua_State* L){ lua_pushnil(L);
lua_setglobal(L, "_locals");
+ pthread_mutex_unlock(&*info->lock);
return info->return_count;
}
@@ -260,14 +265,14 @@ int _thread_clean(lua_State* L){ if(info != NULL && info->L != NULL){
luaI_tsetnil(L, 1, "_");
- if(info->tid != 0){
+ if(info->tid != 0 && !info->done){
#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);
@@ -322,20 +327,26 @@ 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);
+ args->ready_lock = malloc(sizeof * args->ready_lock);
pthread_mutex_init(&*args->ready_lock, NULL);
args->return_count = 0;
+ args->cond = malloc(sizeof * args->cond);
+ pthread_cond_init(&*args->cond, NULL);
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_cond_wait(&*args->cond, &*args->ready_lock);
pthread_mutex_unlock(&*args->ready_lock);
+
+ pthread_cond_destroy(&*args->cond);
+ free(args->cond);
pthread_mutex_destroy(&*args->ready_lock);
free(args->ready_lock);
@@ -518,6 +529,9 @@ void meta_proxy_gen(lua_State* L, struct thread_buffer *buffer, int meta_idx, in int l_buffer_gc(lua_State* L){
struct thread_buffer *buffer = lua_touserdata(L, 1);
pthread_mutex_lock(&*buffer->lock);
+ pthread_mutex_unlock(&*buffer->lock);
+ //race condition here, if something can manage to lock the thread between these two lines
+ //add maybe a closing variable thats checked for
pthread_mutex_destroy(&*buffer->lock);
free(buffer->lock);
diff --git a/tests/kill.lua b/tests/kill.lua index e4010f7..a1fa218 100644 --- a/tests/kill.lua +++ b/tests/kill.lua @@ -9,9 +9,9 @@ end) print(t, e) -os.execute("sleep 5") - print("killing") t:close() t:await() print("after kill") + +os.execute("sleep 0.1"); |
