mirror of
https://github.com/bjornbytes/lovr.git
synced 2024-07-03 04:53:35 +00:00
Thread:wait; Thread:getError; Thread:isRunning;
This commit is contained in:
parent
5c9f234075
commit
109b40bcb4
|
@ -7,7 +7,33 @@ int l_lovrThreadStart(lua_State* L) {
|
||||||
return 0;
|
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[] = {
|
const luaL_Reg lovrThread[] = {
|
||||||
{ "start", l_lovrThreadStart },
|
{ "start", l_lovrThreadStart },
|
||||||
|
{ "wait", l_lovrThreadWait },
|
||||||
|
{ "getError", l_lovrThreadGetError },
|
||||||
|
{ "isRunning", l_lovrThreadIsRunning },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,6 +6,12 @@
|
||||||
static int runner(void* data) {
|
static int runner(void* data) {
|
||||||
Thread* thread = (Thread*) 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
|
||||||
lua_State* L = luaL_newstate();
|
lua_State* L = luaL_newstate();
|
||||||
luaL_openlibs(L);
|
luaL_openlibs(L);
|
||||||
|
@ -35,10 +41,16 @@ static int runner(void* data) {
|
||||||
//luax_preloadmodule(L, "enet", luaopen_enet);
|
//luax_preloadmodule(L, "enet", luaopen_enet);
|
||||||
|
|
||||||
if (luaL_loadbuffer(L, thread->body, strlen(thread->body), "thread") || lua_pcall(L, 0, 0, 0)) {
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mtx_lock(&thread->lock);
|
||||||
|
thread->running = false;
|
||||||
|
mtx_unlock(&thread->lock);
|
||||||
|
lovrRelease(&thread->ref);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,17 +59,44 @@ Thread* lovrThreadCreate(const char* body) {
|
||||||
if (!thread) return NULL;
|
if (!thread) return NULL;
|
||||||
|
|
||||||
thread->body = body;
|
thread->body = body;
|
||||||
|
thread->error = NULL;
|
||||||
|
thread->running = false;
|
||||||
|
mtx_init(&thread->lock, mtx_plain);
|
||||||
|
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrThreadDestroy(const Ref* ref) {
|
void lovrThreadDestroy(const Ref* ref) {
|
||||||
Thread* thread = containerof(ref, Thread);
|
Thread* thread = containerof(ref, Thread);
|
||||||
|
mtx_destroy(&thread->lock);
|
||||||
|
thrd_detach(thread->handle);
|
||||||
free(thread);
|
free(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrThreadStart(Thread* 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;
|
||||||
|
}
|
||||||
|
|
|
@ -1,14 +1,21 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "lib/tinycthread/tinycthread.h"
|
#include "lib/tinycthread/tinycthread.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Ref ref;
|
Ref ref;
|
||||||
thrd_t handle;
|
thrd_t handle;
|
||||||
|
mtx_t lock;
|
||||||
const char* body;
|
const char* body;
|
||||||
|
const char* error;
|
||||||
|
bool running;
|
||||||
} Thread;
|
} Thread;
|
||||||
|
|
||||||
Thread* lovrThreadCreate(const char* body);
|
Thread* lovrThreadCreate(const char* body);
|
||||||
void lovrThreadDestroy(const Ref* ref);
|
void lovrThreadDestroy(const Ref* ref);
|
||||||
void lovrThreadStart(Thread* thread);
|
void lovrThreadStart(Thread* thread);
|
||||||
|
void lovrThreadWait(Thread* thread);
|
||||||
|
const char* lovrThreadGetError(Thread* thread);
|
||||||
|
bool lovrThreadIsRunning(Thread* thread);
|
||||||
|
|
Loading…
Reference in a new issue