fix memory leaking and thread sync problems

This commit is contained in:
2025-03-22 18:24:18 -05:00
parent 239f35389e
commit 73594c8599
2 changed files with 37 additions and 11 deletions

View File

@@ -5413,6 +5413,8 @@ JSC_SCALL(io_slurp,
PHYSFS_close(f);
ret = JS_NewStringLen(js,data, stat.filesize);
free(data);
END:
)

View File

@@ -10,6 +10,8 @@
#include <errno.h>
#include <sys/stat.h>
#include <SDL3/SDL_atomic.h>
#define WOTA_IMPLEMENTATION
#include "wota.h"
#include "qjs_wota.h"
@@ -46,6 +48,9 @@ static struct { char *key; prosperon_rt *value; } *actors = NULL;
static unsigned char *zip_buffer_global = NULL;
static char *prosperon = NULL;
static SDL_AtomicInt shutdown;
static SDL_Thread **runners = NULL;
static void set_actor_state(prosperon_rt *actor);
static Uint32 actor_remove_cb(prosperon_rt *actor, Uint32 id, Uint32 interval)
@@ -437,8 +442,10 @@ void actor_free(prosperon_rt *actor)
JS_FreeContext(js);
JS_FreeRuntime(rt);
free(actor->id);
SDL_UnlockMutex(actor->mutex);
SDL_DestroyMutex(actor->mutex);
SDL_UnlockMutex(actor->msg_mutex);
SDL_DestroyMutex(actor->msg_mutex);
free(actor);
@@ -450,22 +457,26 @@ void actor_free(prosperon_rt *actor)
/* Timer callback adds an event to the queue under evt_mutex. */
Uint32 actor_timer_cb(prosperon_rt *actor, SDL_TimerID id, Uint32 interval)
{
int idx = hmgeti(actor->timers, id);
if (idx == -1) return 0;
SDL_LockMutex(actor->msg_mutex);
int idx = hmgeti(actor->timers, id);
if (idx == -1) goto END;
JSValue cb = actor->timers[idx].value;
hmdel(actor->timers, id);
arrput(actor->events, cb);
SDL_UnlockMutex(actor->msg_mutex);
set_actor_state(actor);
return interval;
END:
SDL_UnlockMutex(actor->msg_mutex);
return 0;
}
/* JS function that schedules a timer. */
JSValue js_actor_delay(JSContext *js, JSValue self, int argc, JSValue *argv)
{
if (!JS_IsFunction(js, argv[0]))
return JS_ThrowReferenceError(js, "Argument must be a function.");
prosperon_rt *actor = JS_GetContextOpaque(js);
double seconds;
JS_ToFloat64(js, &seconds, argv[1]);
@@ -473,7 +484,8 @@ JSValue js_actor_delay(JSContext *js, JSValue self, int argc, JSValue *argv)
Uint32 id = SDL_AddTimerNS(ns, actor_timer_cb, actor);
SDL_LockMutex(actor->msg_mutex);
hmput(actor->timers, id, JS_DupValue(js, argv[0]));
JSValue cb = JS_DupValue(js, argv[0]);
hmput(actor->timers, id, cb);
SDL_UnlockMutex(actor->msg_mutex);
return JS_UNDEFINED;
@@ -533,9 +545,10 @@ void script_startup(prosperon_rt *prt)
}
PHYSFS_Stat stat;
PHYSFS_stat(ENGINE, &stat);
void *data = malloc(stat.filesize);
char *data = malloc(stat.filesize+1);
PHYSFS_readBytes(eng, data, stat.filesize);
PHYSFS_close(eng);
data[stat.filesize] = 0;
/* Called with actor->mutex locked by create_actor(). */
JSValue v = JS_Eval(js, data, (size_t)stat.filesize, ENGINE, JS_EVAL_FLAG_STRICT);
@@ -601,7 +614,7 @@ void script_evalf(JSContext *js, const char *format, ...)
static int crank_actor(void *data)
{
while (true) {
while (!SDL_GetAtomicInt(&shutdown)) {
SDL_LockMutex(queue_mutex);
prosperon_rt *actor = NULL;
if (arrlen(ready_queue) > 0) {
@@ -636,6 +649,7 @@ static void signal_handler(int sig)
JSContext *js = main->context;
script_evalf(js, "prosperon.dispatch('%s')", str);
}
SDL_Quit();
if (sig == SIGTERM || sig == SIGINT) exit(1);
}
@@ -646,6 +660,14 @@ static void exit_handler(void)
JSContext *js = main->context;
script_evalf(js, "prosperon.dispatch('exit')");
}
SDL_SetAtomicInt(&shutdown, 1);
int status;
SDL_BroadcastCondition(queue_cond);
for (int i = 0; i < arrlen(runners); i++)
SDL_WaitThread(runners[i], &status);
SDL_Quit();
}
// Assume these helper functions exist or need to be implemented
@@ -1257,6 +1279,8 @@ static WotaBuffer event2wota(const SDL_Event *event) {
return wb;
}
int main(int argc, char **argv)
{
SDL_Init(SDL_INIT_EVENTS | SDL_INIT_VIDEO);
@@ -1295,7 +1319,7 @@ int main(int argc, char **argv)
/* Start the thread that pumps ready actors, one per logical core. */
for (int i = 0; i < cores; i++) {
SDL_Thread *thread = SDL_CreateThread(crank_actor, "actor_runner", NULL);
SDL_DetachThread(thread);
arrput(runners,thread);
}
/* Set up signal and exit handlers. */