From 2b985e277f06a7086025ab292ddb22b5ded89189 Mon Sep 17 00:00:00 2001 From: ame Date: Thu, 9 May 2024 10:31:26 -0500 Subject: work on memory saftey --- src/thread.c | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/thread.c b/src/thread.c index 441793b..393d3fb 100644 --- a/src/thread.c +++ b/src/thread.c @@ -13,14 +13,15 @@ struct thread_info { str* function; lua_State* L; - int return_count; + int return_count, done; pthread_t tid; - pthread_cond_t cond; pthread_mutex_t lock; }; #include "io.h" +//give the current thread priority to locking thread_lock_lock (fixes race conds) +pthread_mutex_t thread_priority_lock = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t thread_lock_lock = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; larray_t* thread_locks = NULL; @@ -28,6 +29,8 @@ int l_tlock(lua_State* L){ int idx = luaL_checkinteger(L, 1); pthread_mutex_lock(&thread_lock_lock); + pthread_mutex_lock(&thread_priority_lock); + pthread_mutex_unlock(&thread_priority_lock); pthread_mutex_t mutex; if(thread_locks == NULL) thread_locks = larray_init(); int i = 0; @@ -37,9 +40,13 @@ int l_tlock(lua_State* L){ larray_set(&thread_locks, idx, (void*)mutex); } else { pthread_mutex_t m = (pthread_mutex_t)thread_locks->arr[i].value; + pthread_mutex_lock(&thread_priority_lock); + pthread_mutex_unlock(&thread_lock_lock); pthread_mutex_lock(&m); pthread_mutex_lock(&thread_lock_lock); + + pthread_mutex_unlock(&thread_priority_lock); thread_locks->arr[i].value = (void*)m; } @@ -90,6 +97,7 @@ int l_res(lua_State* L){ void* handle_thread(void* _args){ struct thread_info* args = (struct thread_info*)_args; lua_State* L = args->L; + lua_gc(L, LUA_GCSTOP); lua_newtable(L); int res_idx = lua_gettop(L); @@ -117,20 +125,37 @@ int l_await(lua_State* L){ lua_gettable(L, 1); struct thread_info* info = lua_touserdata(L, -1); - pthread_mutex_lock(&info->lock); + if(info->L == NULL) p_fatal("thread has already been cleaned"); + if(!info->done) pthread_mutex_lock(&info->lock); + info->done = 1; for(int i = 0; i != info->return_count; i++){ int ot = lua_gettop(info->L); lua_pushvalue(info->L, ot - info->return_count + i); i_dcopy(info->L, L, NULL); - + lua_settop(info->L, ot); } return info->return_count; } +int l_clean(lua_State* L){ + lua_pushstring(L, "_"); + lua_gettable(L, 1); + struct thread_info* info = lua_touserdata(L, -1); + if(info->L != NULL){ + lua_gc(info->L, LUA_GCRESTART); + lua_gc(info->L, LUA_GCCOLLECT); + lua_close(info->L); + info->L = NULL; + pthread_mutex_destroy(&info->lock); + free(info); + } + return 0; +} + int l_async(lua_State* oL){ lua_State* L = luaL_newstate(); @@ -142,7 +167,6 @@ int l_async(lua_State* oL){ struct thread_info* args = calloc(1, sizeof * args); args->L = L; - args->cond = (pthread_cond_t)PTHREAD_COND_INITIALIZER; args->lock = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&args->lock); args->return_count = 0; @@ -157,7 +181,15 @@ int l_async(lua_State* oL){ lua_newtable(oL); int res_idx = lua_gettop(oL); luaI_tsetcf(oL, res_idx, "await", l_await); + luaI_tsetcf(oL, res_idx, "clean", l_clean); luaI_tsetlud(oL, res_idx, "_", args); + + lua_newtable(oL); + int meta_idx = lua_gettop(oL); + luaI_tsetcf(oL, meta_idx, "__gc", l_clean); + + lua_pushvalue(oL, meta_idx); + lua_setmetatable(oL, res_idx); lua_pushvalue(oL, res_idx); return 1; } -- cgit v1.2.3