diff options
author | Ethan Vrhel <ethanvrhel@gmail.com> | 2021-10-29 20:53:58 -0700 |
---|---|---|
committer | Ethan Vrhel <ethanvrhel@gmail.com> | 2021-10-29 20:53:58 -0700 |
commit | b1f6a4b389c7bcc905e8c2475b83066e8ade919d (patch) | |
tree | a40e9be79f18988e8112cc3a881ef235b570c307 /demos | |
parent | fd131bd575b1b6f771acf6628744b372c6aa4548 (diff) | |
download | ghostpdl-b1f6a4b389c7bcc905e8c2475b83066e8ade919d.tar.gz |
Crude fix to demos/java/mtdemo to avoid a crash
Crash caused by improper handling of multiple threads in gs_jni
modules. Added a way to enable multithreading support in the project
via preprocessor macros, but it currently does not work.
Diffstat (limited to 'demos')
-rw-r--r-- | demos/java/jni/gs_jni/callbacks.cpp | 6 | ||||
-rw-r--r-- | demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp | 19 | ||||
-rw-r--r-- | demos/java/jni/gs_jni/gs_jni.vcxproj | 5 | ||||
-rw-r--r-- | demos/java/jni/gs_jni/instance_data.cpp | 24 | ||||
-rw-r--r-- | demos/java/jni/gs_jni/instance_data.h | 1 | ||||
-rw-r--r-- | demos/java/mtdemo/Main.java | 5 | ||||
-rw-r--r-- | demos/java/mtdemo/Worker.java | 4 |
7 files changed, 54 insertions, 10 deletions
diff --git a/demos/java/jni/gs_jni/callbacks.cpp b/demos/java/jni/gs_jni/callbacks.cpp index 58b11f537..8d9ab2122 100644 --- a/demos/java/jni/gs_jni/callbacks.cpp +++ b/demos/java/jni/gs_jni/callbacks.cpp @@ -75,7 +75,7 @@ int callbacks::stdInFunction(void *callerHandle, char *buf, int len) { jbyteArray byteArray = gsdata->env->NewByteArray(len); gsdata->env->SetByteArrayRegion(byteArray, 0, len, (jbyte *)buf); - code = callIntMethod(gsdata->env, gsdata->stdIn, "onStdIn", STDIN_SIG, (jlong)gsdata->callerHandle, byteArray, (jint)len); + code = callIntMethod(gsdata->env, gsdata->stdIn, "onStdIn", STDIN_SIG, (jlong)gsdata->stdioHandle, byteArray, (jint)len); } return code; } @@ -91,7 +91,7 @@ int callbacks::stdOutFunction(void *callerHandle, const char *str, int len) { jbyteArray byteArray = gsdata->env->NewByteArray(len); gsdata->env->SetByteArrayRegion(byteArray, 0, len, (const jbyte *)str); - code = callIntMethod(gsdata->env, gsdata->stdOut, "onStdOut", STDOUT_SIG, (jlong)gsdata->callerHandle, byteArray, (jint)len); + code = callIntMethod(gsdata->env, gsdata->stdOut, "onStdOut", STDOUT_SIG, (jlong)gsdata->stdioHandle, byteArray, (jint)len); } return code; } @@ -107,7 +107,7 @@ int callbacks::stdErrFunction(void *callerHandle, const char *str, int len) { jbyteArray byteArray = gsdata->env->NewByteArray(len); gsdata->env->SetByteArrayRegion(byteArray, 0, len, (const jbyte *)str); - code = callIntMethod(gsdata->env, gsdata->stdErr, "onStdErr", STDERR_SIG, (jlong)gsdata->callerHandle, byteArray, (jint)len); + code = callIntMethod(gsdata->env, gsdata->stdErr, "onStdErr", STDERR_SIG, (jlong)gsdata->stdioHandle, byteArray, (jint)len); } return code; } diff --git a/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp b/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp index db39d3725..9830a00c7 100644 --- a/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp +++ b/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp @@ -4,6 +4,7 @@ #include <gdevdsp.h> #include <string.h> #include <memory> +#include <assert.h> #include "jni_util.h" #include "callbacks.h" @@ -46,6 +47,8 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1new_1instance idata->instance = gsInstance; + putInstanceData(idata); + return code; } @@ -61,8 +64,13 @@ JNIEXPORT void JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1delete_1instance JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1stdio_1with_1handle (JNIEnv *env, jclass, jlong instance, jobject stdIn, jobject stdOut, jobject stdErr, jlong callerHandle) { + GSInstanceData *idata = findDataFromInstance((void *)instance); + assert(idata); + + idata->stdioHandle = (void *)callerHandle; + int code = gsapi_set_stdio_with_handle((void *)instance, callbacks::stdInFunction, - callbacks::stdOutFunction, callbacks::stdErrFunction, (void *)callerHandle); + callbacks::stdOutFunction, callbacks::stdErrFunction, idata); if (code == 0) { callbacks::setJNIEnv((void *)instance, env); @@ -74,8 +82,13 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1stdio_1with_1ha JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1stdio (JNIEnv *env, jclass, jlong instance, jobject stdIn, jobject stdOut, jobject stdErr) { - int code = gsapi_set_stdio((void *)instance, callbacks::stdInFunction, - callbacks::stdOutFunction, callbacks::stdErrFunction); + GSInstanceData *idata = findDataFromInstance((void *)instance); + assert(idata); + + idata->stdioHandle = NULL; + + int code = gsapi_set_stdio_with_handle((void *)instance, callbacks::stdInFunction, + callbacks::stdOutFunction, callbacks::stdErrFunction, idata); if (code == 0) { callbacks::setJNIEnv((void *)instance, env); diff --git a/demos/java/jni/gs_jni/gs_jni.vcxproj b/demos/java/jni/gs_jni/gs_jni.vcxproj index 369670fc3..201a59966 100644 --- a/demos/java/jni/gs_jni/gs_jni.vcxproj +++ b/demos/java/jni/gs_jni/gs_jni.vcxproj @@ -98,7 +98,7 @@ <GenerateDebugInformation>true</GenerateDebugInformation> <EnableUAC>false</EnableUAC> <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalLibraryDirectories>$(SolutionDir)..\..\..\..\debugbin;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalLibraryDirectories>$(SolutionDir)..\..\..\..\bin;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> @@ -120,6 +120,7 @@ <OptimizeReferences>true</OptimizeReferences> <GenerateDebugInformation>true</GenerateDebugInformation> <EnableUAC>false</EnableUAC> + <AdditionalLibraryDirectories>$(SolutionDir)..\..\..\..\bin;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> @@ -138,7 +139,7 @@ <GenerateDebugInformation>true</GenerateDebugInformation> <EnableUAC>false</EnableUAC> <AdditionalDependencies>gpdldll64.lib;%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalLibraryDirectories>$(SolutionDir)..\..\..\..\debugbin;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalLibraryDirectories>$(SolutionDir)..\..\..\..\bin;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> diff --git a/demos/java/jni/gs_jni/instance_data.cpp b/demos/java/jni/gs_jni/instance_data.cpp index ca297328a..7543afdc6 100644 --- a/demos/java/jni/gs_jni/instance_data.cpp +++ b/demos/java/jni/gs_jni/instance_data.cpp @@ -4,33 +4,54 @@ #include <assert.h> +static GSInstanceData g_global; // Global instance for faster multithreading + +#if defined(ALLOW_MT) + static std::unordered_map<void *, GSInstanceData *> g_inst2Data; // instance -> data static std::unordered_map<void *, GSInstanceData *> g_hand2Data; // caller handle -> data +#endif + GSInstanceData *putInstanceData(GSInstanceData *data) { +#if defined(ALLOW_MT) assert(g_inst2Data.find(data->instance) == g_inst2Data.end() && g_hand2Data.find(data->callerHandle) == g_hand2Data.end()); g_inst2Data[data->instance] = data; g_hand2Data[data->callerHandle] = data; return data; + +#else + delete data; + return &g_global; +#endif } GSInstanceData *findDataFromInstance(void *instance) { +#if defined(ALLOW_MT) auto it = g_inst2Data.find(instance); return it == g_inst2Data.end() ? NULL : it->second; +#else + return &g_global; +#endif } GSInstanceData *findDataFromHandle(void *callerHandle) { +#if defined(ALLOW_MT) auto it = g_hand2Data.find(callerHandle); return it == g_hand2Data.end() ? NULL : it->second; +#else + return &g_global; +#endif } void deleteDataFromInstance(void *instance) { +#if defined(ALLOW_MT) auto i2dit = g_inst2Data.find(instance); if (i2dit != g_inst2Data.end()) { @@ -42,10 +63,12 @@ void deleteDataFromInstance(void *instance) g_inst2Data.erase(i2dit); g_hand2Data.erase(h2dit); } +#endif } void deleteDataFromHandle(void *callerHandle) { +#if defined(ALLOW_MT) auto h2dit = g_hand2Data.find(callerHandle); if (h2dit != g_hand2Data.end()) { @@ -57,4 +80,5 @@ void deleteDataFromHandle(void *callerHandle) g_hand2Data.erase(i2dit); g_inst2Data.erase(h2dit); } +#endif } diff --git a/demos/java/jni/gs_jni/instance_data.h b/demos/java/jni/gs_jni/instance_data.h index 2405e128e..4274dbe24 100644 --- a/demos/java/jni/gs_jni/instance_data.h +++ b/demos/java/jni/gs_jni/instance_data.h @@ -7,6 +7,7 @@ class GSInstanceData public: void *instance = NULL; void *callerHandle = NULL; + void *stdioHandle = NULL; JNIEnv *env; diff --git a/demos/java/mtdemo/Main.java b/demos/java/mtdemo/Main.java index a8c2232a6..cdc3c9a01 100644 --- a/demos/java/mtdemo/Main.java +++ b/demos/java/mtdemo/Main.java @@ -1,5 +1,7 @@ import com.artifex.gsjava.GSInstance; +import java.util.Scanner; + public class Main { public static void main(String[] args) { @@ -12,6 +14,9 @@ public class Main { } catch (NumberFormatException e) { } } + //Scanner in = new Scanner(System.in); + //in.nextLine(); + Worker[] workers = new Worker[workerCount]; for (int i = 0; i < workers.length; i++) { diff --git a/demos/java/mtdemo/Worker.java b/demos/java/mtdemo/Worker.java index c6ed6f44a..2b7b960bd 100644 --- a/demos/java/mtdemo/Worker.java +++ b/demos/java/mtdemo/Worker.java @@ -45,8 +45,8 @@ public class Worker implements Runnable { try { gsInstance = createGSInstance(); - StdIO io = new StdIO(); - gsInstance.set_stdio(io, null, null); + //StdIO io = new StdIO(); + //gsInstance.set_stdio(io, null, null); if (!outPDF.exists()) outPDF.createNewFile(); |