Skip to content

Commit

Permalink
Merge pull request #79 from Berstanio/feat/thread-attach-rework
Browse files Browse the repository at this point in the history
Thread attach rework
  • Loading branch information
Berstanio authored Nov 27, 2024
2 parents c570610 + 166743e commit 3987373
Show file tree
Hide file tree
Showing 13 changed files with 411 additions and 6 deletions.
170 changes: 170 additions & 0 deletions .github/workflows/build-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
name: Build and test pullrequest

on:
pull_request:
branches: [ master ]
permissions:
contents: read

env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true

jobs:
test-macos:
runs-on: macos-14
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
submodules: 'recursive'

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '17'

- name: Setup Gradle
uses: gradle/gradle-build-action@v2

- name: Build macOS natives
run: |
# See https://github.com/actions/virtual-environments/issues/2557
sudo mv /Library/Developer/CommandLineTools/SDKs/* /tmp
sudo mv /Applications/Xcode.app /Applications/Xcode.app.bak
sudo mv /Applications/Xcode_15.4.0.app /Applications/Xcode.app
sudo xcode-select -switch /Applications/Xcode.app
/usr/bin/xcodebuild -version
./gradlew build_macos
./gradlew jniGen jnigenBuildAllMacOsX
- name: Run test on macos
run: |
./gradlew test
test-linux:
runs-on: ubuntu-20.04
container:
image: ubuntu:18.04
steps:
- name: Install dependencies into minimal dockerfile
run: |
# ubuntu dockerfile is very minimal (only 122 packages are installed)
# need to install updated git (from official git ppa)
apt update
apt install -y software-properties-common
add-apt-repository ppa:git-core/ppa -y
# install dependencies expected by other steps
apt update
apt install -y git \
curl \
ca-certificates \
wget \
bzip2 \
zip \
unzip \
xz-utils \
maven \
ant sudo locales make texinfo
# set Locale to en_US.UTF-8 (avoids hang during compilation)
locale-gen en_US.UTF-8
echo "LANG=en_US.UTF-8" >> $GITHUB_ENV
echo "LANGUAGE=en_US.UTF-8" >> $GITHUB_ENV
echo "LC_ALL=en_US.UTF-8" >> $GITHUB_ENV
- uses: actions/checkout@v2
with:
fetch-depth: 0
submodules: 'recursive'

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '17'

- name: Setup Gradle
uses: gradle/gradle-build-action@v2

- name: Install cross-compilation toolchains
run: |
sudo apt update
sudo apt install -y --force-yes gcc g++
sudo apt install -y --force-yes gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev-arm64-cross
sudo apt install -y --force-yes gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc6-dev-armhf-cross
sudo apt install -y --force-yes gcc-riscv64-linux-gnu g++-riscv64-linux-gnu libc6-dev-riscv64-cross
- name: Build Linux natives
run: |
./gradlew build_linux
./gradlew jnigen jnigenBuildAllLinux
- name: Run test on linux
run: |
./gradlew test
natives-windows:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
submodules: 'recursive'

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '17'

- name: Setup Gradle
uses: gradle/gradle-build-action@v2

- name: Install cross-compilation toolchains
run: |
sudo apt update
sudo apt install -y --force-yes mingw-w64 lib32z1
- name: Build Windows natives
run: |
./gradlew build_windows
./gradlew jnigen jnigenBuildAllWindows
- name: Pack artifacts
run: |
find . -name "*.a" -o -name "*.dll" -o -name "*.dylib" -o -name "*.so" | grep "libs" > native-files-list
zip natives-windows -@ < native-files-list
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: natives-windows.zip
path: natives-windows.zip

test-windows:
runs-on: windows-latest
needs: [natives-windows]
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
submodules: 'recursive'

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '17'

- name: Setup Gradle
uses: gradle/gradle-build-action@v2

- name: Download natives-windows artifact
uses: actions/download-artifact@v3
with:
name: natives-windows.zip

- name: Run windows tests
run: |
./gradlew test
29 changes: 28 additions & 1 deletion .github/workflows/build-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,36 @@ jobs:
name: natives-android.zip
path: natives-android.zip

test-windows:
runs-on: windows-latest
needs: [natives-windows]
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
submodules: 'recursive'

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '17'

- name: Setup Gradle
uses: gradle/gradle-build-action@v2

- name: Download natives-windows artifact
uses: actions/download-artifact@v3
with:
name: natives-windows.zip

- name: Run windows tests
run: |
./gradlew test
publish:
runs-on: ubuntu-20.04
needs: [natives-macos, natives-linux, natives-windows, natives-ios, natives-android]
needs: [natives-macos, natives-linux, natives-windows, natives-ios, natives-android, test-windows]
steps:
- uses: actions/checkout@v2
with:
Expand Down
2 changes: 1 addition & 1 deletion gdx-jnigen-generator-test/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ dependencies {
testRuntimeOnly fileTree(dir: file("build/jnigen/libs"), include: '*natives-desktop.jar')
if (HostDetection.os === Os.Windows) {
testImplementation "com.badlogicgames.jnigen:jnigen-runtime:3.0.0-SNAPSHOT"
testImplementation "com.badlogicgames.jnigen:jnigen-runtime:3.0.0-SNAPSHOT:natives-desktop"
testImplementation "com.badlogicgames.jnigen:jnigen-runtime-platform:3.0.0-SNAPSHOT:natives-desktop"
} else {
testImplementation project(path: ":jnigen-runtime")
testImplementation project(path: ":jnigen-runtime", configuration: "archives")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public final class Constants {

public static final byte UNSIGNED_INT = 10;

public static final byte boolean_r = 10;
public static final byte final_r = 10;

public static final byte special1 = 10;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,16 @@ public static boolean validateString(CSizedIntPointer str) {
return 0;
*/

public static void call_callback_in_thread(ClosureObject<thread_callback> thread_callback) {
call_callback_in_thread_internal(thread_callback.getFnPtr());
}

static private native void call_callback_in_thread_internal(long thread_callback);/*
HANDLE_JAVA_EXCEPTION_START()
call_callback_in_thread((void *(*)(void *))thread_callback);
HANDLE_JAVA_EXCEPTION_END()
*/

public interface methodWithCallbackBooleanArg extends com.badlogic.gdx.jnigen.runtime.closure.Closure {

com.badlogic.gdx.jnigen.runtime.c.CTypeInfo[] __ffi_cache = new com.badlogic.gdx.jnigen.runtime.c.CTypeInfo[] { FFITypes.getCTypeInfo(-2), FFITypes.getCTypeInfo(0) };
Expand Down Expand Up @@ -1354,6 +1364,21 @@ default void invoke(com.badlogic.gdx.jnigen.runtime.ffi.JavaTypeWrapper[] parame
}
}

public interface thread_callback extends com.badlogic.gdx.jnigen.runtime.closure.Closure {

com.badlogic.gdx.jnigen.runtime.c.CTypeInfo[] __ffi_cache = new com.badlogic.gdx.jnigen.runtime.c.CTypeInfo[] { FFITypes.getCTypeInfo(-1), FFITypes.getCTypeInfo(-1) };

VoidPointer thread_callback_call(VoidPointer arg0);

default com.badlogic.gdx.jnigen.runtime.c.CTypeInfo[] functionSignature() {
return __ffi_cache;
}

default void invoke(com.badlogic.gdx.jnigen.runtime.ffi.JavaTypeWrapper[] parameters, com.badlogic.gdx.jnigen.runtime.ffi.JavaTypeWrapper returnType) {
returnType.setValue(thread_callback_call(new VoidPointer(parameters[0].asLong(), false)));
}
}

public interface methodWithCallbackTestStructReturn extends com.badlogic.gdx.jnigen.runtime.closure.Closure {

com.badlogic.gdx.jnigen.runtime.c.CTypeInfo[] __ffi_cache = new com.badlogic.gdx.jnigen.runtime.c.CTypeInfo[] { FFITypes.getCTypeInfo(19) };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,4 +229,17 @@ public void testCallbackDoubleReturn() {
assertEquals(55.55, ret);
closureObject.free();
}

@Test
public void closureFromThread() {
AtomicReference<String> spawnedThreadName = new AtomicReference<>();
ClosureObject<thread_callback> closureObject = ClosureObject.fromClosure((arg) -> {
spawnedThreadName.set(Thread.currentThread().getName());
return arg;
});
call_callback_in_thread(closureObject);
assertNotEquals(spawnedThreadName.get(), Thread.currentThread().getName());
assertTrue(spawnedThreadName.get().startsWith("Thread-"));
closureObject.free();
}
}
23 changes: 23 additions & 0 deletions gdx-jnigen-generator-test/src/test/resources/test_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,4 +414,27 @@ void ensureParsed(AnonymousStructNoField, AnonymousStructField, AnonymousStructF
void weirdPointer(FILE *_file) {}
void constArrayParameter(const TestStruct structs[]) {}

#ifdef _WIN32
#include <windows.h>

DWORD WINAPI thread_wrapper(LPVOID param) {
auto callback = reinterpret_cast<void* (*)(void*)>(param);
callback(nullptr);
return 0;
}

void call_callback_in_thread(void* (*thread_callback)(void*)) {
HANDLE thread = CreateThread(NULL, 0, thread_wrapper, reinterpret_cast<LPVOID>(thread_callback), 0, NULL);
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
}
#else
#include <pthread.h>

void call_callback_in_thread(void* (*thread_callback)(void*)) {
pthread_t thread;
pthread_create(&thread, NULL, thread_callback, NULL);
pthread_join(thread, NULL);
}
#endif

3 changes: 2 additions & 1 deletion gdx-jnigen-generator-test/src/test/resources/test_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ extern "C" {
#define SIGNED_DOUBLE -10.5
#define UNSIGNED_HEX_INT 0x5B
#define SIGNED_HEX_INT -0x5B
#define boolean 10
#define final 10
#define special1 10L
#define special2 10LLU
#define special3 10.5
Expand Down Expand Up @@ -268,6 +268,7 @@ const char* returnThrownCauseMessage(methodWithThrowingCallback fnPtr);
char* returnString(void);
bool validateString(char* str);

void call_callback_in_thread(void* (*thread_callback)(void*));
#ifdef __cplusplus
}
#endif
1 change: 1 addition & 0 deletions gdx-jnigen-runtime/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ jnigen {

headerDirs += ["build/libffi-build/${combined}/include/", "src/main/native"]
cppIncludes += ["src/main/native/*.cpp"]
cIncludes += ["src/main/native/*.c"]
cFlags += " -std=c11 -fexceptions "
cppFlags += " -std=c++11 -fexceptions "
libraries += file("build/libffi-build/${combined}/lib/libffi.a").absolutePath
Expand Down
13 changes: 11 additions & 2 deletions gdx-jnigen-runtime/src/main/native/CHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <string.h>
#include <ffi.h>
#include <jnigen.h>
#include <jni_env_tls.h>

#ifdef __linux__
#include <dlfcn.h>
Expand Down Expand Up @@ -90,7 +91,8 @@ static inline void calculateAlignmentAndOffset(ffi_type* type, bool isStruct) {
}

void callbackHandler(ffi_cif* cif, void* result, void** args, void* user) {
ATTACH_ENV()
JNIEnv* env;
tls_attach_jni_env(gJVM, &env);
closure_info* info = (closure_info*) user;
char backingBuffer[info->argumentSize];
jobject jBuffer = NULL;
Expand Down Expand Up @@ -130,7 +132,6 @@ void callbackHandler(ffi_cif* cif, void* result, void** args, void* user) {
} else {
ENDIAN_INTCPY(result, rtype->size, &ret, sizeof(jlong));
}
DETACH_ENV()
}

JNIEXPORT jint JNICALL Java_com_badlogic_gdx_jnigen_runtime_CHandler_getPointerSize(JNIEnv* env, jclass clazz) {
Expand Down Expand Up @@ -372,3 +373,11 @@ JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_jnigen_runtime_CHandler_clone(JNIE
return reinterpret_cast<jlong>(dst);
}

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
init_tls();
return JNI_VERSION_1_6;
}

JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
cleanup_tls();
}
3 changes: 3 additions & 0 deletions gdx-jnigen-runtime/src/main/native/CHandler.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 3987373

Please sign in to comment.