From: Olaf Wintermann Date: Fri, 18 Jul 2025 18:53:15 +0000 (+0200) Subject: add invokeMainThread X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;h=7452eb2e65105cbfd7f8fe911a0e063533307b6e;p=rssreader.git add invokeMainThread --- diff --git a/ui-java/src/main/java/de/unixwork/ui/ThreadCallback.java b/ui-java/src/main/java/de/unixwork/ui/ThreadCallback.java new file mode 100644 index 0000000..d8c7512 --- /dev/null +++ b/ui-java/src/main/java/de/unixwork/ui/ThreadCallback.java @@ -0,0 +1,6 @@ +package de.unixwork.ui; + +@FunctionalInterface +public interface ThreadCallback { + public void callback(); +} diff --git a/ui-java/src/main/java/de/unixwork/ui/Toolkit.java b/ui-java/src/main/java/de/unixwork/ui/Toolkit.java index 6f7fee7..90d2a5d 100644 --- a/ui-java/src/main/java/de/unixwork/ui/Toolkit.java +++ b/ui-java/src/main/java/de/unixwork/ui/Toolkit.java @@ -40,6 +40,10 @@ public class Toolkit { protected MemorySegment getValue; protected MemorySegment sourceListGetValue; + protected MemorySegment threadFuncPtr; + + private HashMap threadCallbacks = new HashMap<>(); + private Toolkit(String appName) { // load shared library System.loadLibrary("uitk"); @@ -175,6 +179,23 @@ public class Toolkit { } catch (IllegalAccessException e) { throw new RuntimeException(e); } + + // threadfunc wrapper + try { + MethodHandle threadFuncCallback = MethodHandles.lookup().findStatic( + Thread.class, + "threadFunc", + MethodType.methodType(int.class, MemorySegment.class)); + FunctionDescriptor threadFuncDescriptor = FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS); + threadFuncPtr = linker.upcallStub( + threadFuncCallback, + threadFuncDescriptor, + staticArena); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } } public static Toolkit getInstance() { @@ -470,4 +491,29 @@ public class Toolkit { Context listCtx = Toolkit.getInstance().getContext(listCtxPtr); return listCtx.getList((int)listIndex); } + + private static int threadFunc(MemorySegment ptr) { + int key = (int)ptr.address(); + Toolkit toolkit = Toolkit.getInstance(); + ThreadCallback callback = toolkit.threadCallbacks.get(key); + if(callback != null) { + callback.callback(); + } + return 0; + } + + private synchronized ThreadCallback getThreadCallback(int key) { + return threadCallbacks.remove(key); + } + + public synchronized void invokeMainThread(ThreadCallback callback) { + int key = threadCallbacks.size(); + threadCallbacks.put(key, callback); + MemorySegment ckey = MemorySegment.ofAddress((long)key); + try { + ToolkitFuncs.getInstance().call_mainthread.invoke(threadFuncPtr, ckey); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } } diff --git a/ui-java/src/main/java/de/unixwork/ui/ToolkitFuncs.java b/ui-java/src/main/java/de/unixwork/ui/ToolkitFuncs.java index cab31f3..4d6655e 100644 --- a/ui-java/src/main/java/de/unixwork/ui/ToolkitFuncs.java +++ b/ui-java/src/main/java/de/unixwork/ui/ToolkitFuncs.java @@ -60,6 +60,8 @@ public class ToolkitFuncs { public MethodHandle text_set; public MethodHandle text_get; + public MethodHandle call_mainthread; + // some libc stuff public MethodHandle malloc; public MethodHandle free; @@ -128,6 +130,8 @@ public class ToolkitFuncs { MemorySegment text_set_addr = lib.find("ui_text_set").orElseThrow(); MemorySegment text_get_addr = lib.find("ui_text_get").orElseThrow(); + MemorySegment call_mainthread_addr = lib.find("ui_call_mainthread").orElseThrow(); + MemorySegment malloc_addr = lib.find("malloc").orElseThrow(); MemorySegment free_addr = lib.find("free").orElseThrow(); @@ -186,6 +190,8 @@ public class ToolkitFuncs { text_set = linker.downcallHandle(text_set_addr, sigv_mm); text_get = linker.downcallHandle(text_get_addr, sigm_m); + call_mainthread = linker.downcallHandle(call_mainthread_addr, sigv_mm); + malloc = linker.downcallHandle(malloc_addr, sigm_l); free = linker.downcallHandle(free_addr, sigv_m); }