Add os_thread_attach/os_thread_detach;

These are called when creating/destroying Thread objects.  It's
currently only implemented on Android, where it attaches/detaches the
Java VM to the thread.  This allows JNI calls to be used on threads.

However I don't think e.g. `lovr.system.requestPermission` will work on
a thread yet, because it uses the global JNI env from the main thread
instead of the thread's JNI env.  Still, attaching/detaching the VM is
an improvement and will allow well-behaved JNI methods to work on
threads now.

I don't know how expensive this is, yolo.
This commit is contained in:
bjorn 2023-09-05 16:20:32 -07:00
parent 81e1c8fbad
commit 14cb2ed368
7 changed files with 49 additions and 0 deletions

View File

@ -149,6 +149,9 @@ bool os_vm_free(void* p, size_t size);
bool os_vm_commit(void* p, size_t size);
bool os_vm_release(void* p, size_t size);
void os_thread_attach(void);
void os_thread_detach(void);
void os_poll_events(void);
void os_on_quit(fn_quit* callback);
void os_on_focus(fn_focus* callback);

View File

@ -281,6 +281,15 @@ bool os_vm_release(void* p, size_t size) {
return !madvise(p, size, MADV_DONTNEED);
}
void os_thread_attach(void) {
JNIEnv* jni;
(*state.app->activity->vm)->AttachCurrentThread(state.app->activity->vm, &jni, NULL);
}
void os_thread_detach(void) {
(*state.app->activity->vm)->DetachCurrentThread(state.app->activity->vm);
}
// Notes about polling:
// - Stop polling if a destroy is requested to give the application a chance to shut down.
// Otherwise this loop would still wait for an event and the app would seem unresponsive.

View File

@ -64,6 +64,14 @@ bool os_vm_release(void* p, size_t size) {
return !madvise(p, size, MADV_DONTNEED);
}
void os_thread_attach(void) {
//
}
void os_thread_detach(void) {
//
}
void os_window_message_box(const char* message) {
//
}

View File

@ -105,6 +105,14 @@ void os_on_permission(fn_permission* callback) {
state.onPermissionEvent = callback;
}
void os_thread_attach(void) {
//
}
void os_thread_detach(void) {
//
}
void os_window_message_box(const char* message) {
//
}

View File

@ -246,6 +246,14 @@ void os_request_permission(os_permission permission) {
//
}
void os_thread_attach(void) {
//
}
void os_thread_detach(void) {
//
}
void os_poll_events(void) {
//
}

View File

@ -116,6 +116,14 @@ bool os_vm_release(void* p, size_t size) {
return VirtualFree(p, 0, MEM_DECOMMIT);
}
void os_thread_attach(void) {
//
}
void os_thread_detach(void) {
//
}
void os_on_permission(fn_permission* callback) {
//
}

View File

@ -1,6 +1,7 @@
#include "thread/thread.h"
#include "data/blob.h"
#include "event/event.h"
#include "core/os.h"
#include "util.h"
#include "lib/tinycthread/tinycthread.h"
#include <math.h>
@ -78,8 +79,12 @@ Channel* lovrThreadGetChannel(const char* name) {
static int threadFunction(void* data) {
Thread* thread = data;
os_thread_attach();
char* error = thread->function(thread, thread->body, thread->arguments, thread->argumentCount);
os_thread_detach();
mtx_lock(&thread->lock);
thread->running = false;
if (error) {