Thread:wait; Thread:getError; Thread:isRunning;

This commit is contained in:
bjorn 2018-02-12 21:30:00 -08:00
parent 5c9f234075
commit 109b40bcb4
3 changed files with 75 additions and 3 deletions

View File

@ -7,7 +7,33 @@ int l_lovrThreadStart(lua_State* L) {
return 0;
}
int l_lovrThreadWait(lua_State* L) {
Thread* thread = luax_checktype(L, 1, Thread);
lovrThreadWait(thread);
return 0;
}
int l_lovrThreadGetError(lua_State* L) {
Thread* thread = luax_checktype(L, 1, Thread);
const char* error = lovrThreadGetError(thread);
if (error) {
lua_pushstring(L, error);
} else {
lua_pushnil(L);
}
return 1;
}
int l_lovrThreadIsRunning(lua_State* L) {
Thread* thread = luax_checktype(L, 1, Thread);
lua_pushboolean(L, thread->running);
return 1;
}
const luaL_Reg lovrThread[] = {
{ "start", l_lovrThreadStart },
{ "wait", l_lovrThreadWait },
{ "getError", l_lovrThreadGetError },
{ "isRunning", l_lovrThreadIsRunning },
{ NULL, NULL }
};

View File

@ -6,6 +6,12 @@
static int runner(void* data) {
Thread* thread = (Thread*) data;
lovrRetain(&thread->ref);
mtx_lock(&thread->lock);
thread->running = true;
thread->error = NULL;
mtx_unlock(&thread->lock);
// Lua state
lua_State* L = luaL_newstate();
luaL_openlibs(L);
@ -35,10 +41,16 @@ static int runner(void* data) {
//luax_preloadmodule(L, "enet", luaopen_enet);
if (luaL_loadbuffer(L, thread->body, strlen(thread->body), "thread") || lua_pcall(L, 0, 0, 0)) {
printf("error running thread\n");
thread->error = lua_tostring(L, -1);
//lua_getglobal(lovr, "threaderror");
lovrRelease(&thread->ref);
return 1;
}
mtx_lock(&thread->lock);
thread->running = false;
mtx_unlock(&thread->lock);
lovrRelease(&thread->ref);
return 0;
}
@ -47,17 +59,44 @@ Thread* lovrThreadCreate(const char* body) {
if (!thread) return NULL;
thread->body = body;
thread->error = NULL;
thread->running = false;
mtx_init(&thread->lock, mtx_plain);
return thread;
}
void lovrThreadDestroy(const Ref* ref) {
Thread* thread = containerof(ref, Thread);
mtx_destroy(&thread->lock);
thrd_detach(thread->handle);
free(thread);
}
void lovrThreadStart(Thread* thread) {
if (thrd_create(&thread->handle, runner, thread)) {
//
bool running = lovrThreadIsRunning(thread);
if (running) {
return;
}
if (thrd_create(&thread->handle, runner, thread) != thrd_success) {
lovrThrow("Could not create thread...sorry");
return;
}
}
void lovrThreadWait(Thread* thread) {
thrd_join(thread->handle, NULL);
}
bool lovrThreadIsRunning(Thread* thread) {
mtx_lock(&thread->lock);
bool running = thread->running;
mtx_unlock(&thread->lock);
return running;
}
const char* lovrThreadGetError(Thread* thread) {
return thread->error;
}

View File

@ -1,14 +1,21 @@
#include "util.h"
#include "lib/tinycthread/tinycthread.h"
#include <stdbool.h>
#pragma once
typedef struct {
Ref ref;
thrd_t handle;
mtx_t lock;
const char* body;
const char* error;
bool running;
} Thread;
Thread* lovrThreadCreate(const char* body);
void lovrThreadDestroy(const Ref* ref);
void lovrThreadStart(Thread* thread);
void lovrThreadWait(Thread* thread);
const char* lovrThreadGetError(Thread* thread);
bool lovrThreadIsRunning(Thread* thread);