summaryrefslogtreecommitdiff
path: root/demos
diff options
context:
space:
mode:
authorEthan Vrhel <ethanvrhel@gmail.com>2021-10-29 20:53:58 -0700
committerEthan Vrhel <ethanvrhel@gmail.com>2021-10-29 20:53:58 -0700
commitb1f6a4b389c7bcc905e8c2475b83066e8ade919d (patch)
treea40e9be79f18988e8112cc3a881ef235b570c307 /demos
parentfd131bd575b1b6f771acf6628744b372c6aa4548 (diff)
downloadghostpdl-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.cpp6
-rw-r--r--demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp19
-rw-r--r--demos/java/jni/gs_jni/gs_jni.vcxproj5
-rw-r--r--demos/java/jni/gs_jni/instance_data.cpp24
-rw-r--r--demos/java/jni/gs_jni/instance_data.h1
-rw-r--r--demos/java/mtdemo/Main.java5
-rw-r--r--demos/java/mtdemo/Worker.java4
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();