summaryrefslogtreecommitdiff
path: root/demos
diff options
context:
space:
mode:
authorEthan Vrhel <ethanvrhel@gmail.com>2021-10-29 17:08:41 -0700
committerEthan Vrhel <ethanvrhel@gmail.com>2021-10-29 17:09:08 -0700
commitfd131bd575b1b6f771acf6628744b372c6aa4548 (patch)
tree831aea4743bbd65b5e3f390ae2d24aa1f87eadf4 /demos
parentff1882c1e0915d2aad7689ba3c20adb3de64188e (diff)
downloadghostpdl-fd131bd575b1b6f771acf6628744b372c6aa4548.tar.gz
Updating gs_jni to support multithreading
Diffstat (limited to 'demos')
-rw-r--r--demos/java/jni/gs_jni/callbacks.cpp173
-rw-r--r--demos/java/jni/gs_jni/callbacks.h24
-rw-r--r--demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp55
-rw-r--r--demos/java/jni/gs_jni/gs_jni.vcxproj2
-rw-r--r--demos/java/jni/gs_jni/gs_jni.vcxproj.filters6
-rw-r--r--demos/java/jni/gs_jni/instance_data.cpp60
-rw-r--r--demos/java/jni/gs_jni/instance_data.h28
7 files changed, 233 insertions, 115 deletions
diff --git a/demos/java/jni/gs_jni/callbacks.cpp b/demos/java/jni/gs_jni/callbacks.cpp
index f54678318..58b11f537 100644
--- a/demos/java/jni/gs_jni/callbacks.cpp
+++ b/demos/java/jni/gs_jni/callbacks.cpp
@@ -1,9 +1,11 @@
#include "callbacks.h"
#include "jni_util.h"
+#include "instance_data.h"
#include <string.h>
#include <unordered_map>
+#include <assert.h>
#define STDIN_SIG "(J[BI)I"
#define STDOUT_SIG "(J[BI)I"
@@ -32,46 +34,19 @@ Lcom/artifex/gsjava/IntReference;)I"
using namespace util;
-class GSInstanceData
-{
-public:
- JNIEnv *env;
-
- jobject stdIn = NULL;
- jobject stdOut = NULL;
- jobject stdErr = NULL;
-
- jobject poll = NULL;
-
- jobject displayCallback = NULL;
-
- jobject callout = NULL;
-};
-
-static std::unordered_map<void *, GSInstanceData> g_instanceData;
-
-static inline GSInstanceData *getInstanceData(void *instance)
-{
- GSInstanceData *gsdata;
-
- auto it = g_instanceData.find(instance);
- if (it == g_instanceData.end())
- gsdata = &(g_instanceData[instance] = GSInstanceData());
- else
- gsdata = &it->second;
-
- return gsdata;
-}
-
void callbacks::setJNIEnv(void *instance, JNIEnv *env)
{
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromInstance(instance);
+ assert(gsdata);
+
gsdata->env = env;
}
void callbacks::setIOCallbacks(void *instance, jobject stdIn, jobject stdOut, jobject stdErr)
{
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromInstance(instance);
+ assert(gsdata);
+
if (gsdata->env)
{
if (gsdata->stdIn)
@@ -93,12 +68,14 @@ int callbacks::stdInFunction(void *callerHandle, char *buf, int len)
{
int code = 0;
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromHandle(callerHandle);
+ assert(gsdata);
+
if (gsdata->env && gsdata->stdIn)
{
jbyteArray byteArray = gsdata->env->NewByteArray(len);
gsdata->env->SetByteArrayRegion(byteArray, 0, len, (jbyte *)buf);
- code = callIntMethod(gsdata->env, gsdata->stdIn, "onStdIn", STDIN_SIG, (jlong)callerHandle, byteArray, (jint)len);
+ code = callIntMethod(gsdata->env, gsdata->stdIn, "onStdIn", STDIN_SIG, (jlong)gsdata->callerHandle, byteArray, (jint)len);
}
return code;
}
@@ -107,12 +84,14 @@ int callbacks::stdOutFunction(void *callerHandle, const char *str, int len)
{
int code = 0;
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromHandle(callerHandle);
+ assert(gsdata);
+
if (gsdata->env && gsdata->stdOut)
{
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)callerHandle, byteArray, (jint)len);
+ code = callIntMethod(gsdata->env, gsdata->stdOut, "onStdOut", STDOUT_SIG, (jlong)gsdata->callerHandle, byteArray, (jint)len);
}
return code;
}
@@ -121,19 +100,23 @@ int callbacks::stdErrFunction(void *callerHandle, const char *str, int len)
{
int code = 0;
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromHandle(callerHandle);
+ assert(gsdata);
+
if (gsdata->env && gsdata->stdErr)
{
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)callerHandle, byteArray, (jint)len);
+ code = callIntMethod(gsdata->env, gsdata->stdErr, "onStdErr", STDERR_SIG, (jlong)gsdata->callerHandle, byteArray, (jint)len);
}
return code;
}
void callbacks::setPollCallback(void *instance, jobject poll)
{
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromInstance(instance);
+ assert(gsdata);
+
if (gsdata->env)
{
if (gsdata->poll)
@@ -143,21 +126,25 @@ void callbacks::setPollCallback(void *instance, jobject poll)
}
}
-int callbacks::pollFunction(void *instance, void *callerHandle)
+int callbacks::pollFunction(void *callerHandle)
{
int code = 0;
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromHandle(callerHandle);
+ assert(gsdata);
+
if (gsdata->env && gsdata->poll)
{
- code = callIntMethod(gsdata->env, gsdata->poll, "onPoll", POLL_SIG, (jlong)callerHandle);
+ code = callIntMethod(gsdata->env, gsdata->poll, "onPoll", POLL_SIG, (jlong)gsdata->callerHandle);
}
return code;
}
void callbacks::setDisplayCallback(void *instance, jobject displayCallback)
{
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromInstance(instance);
+ assert(gsdata);
+
if (gsdata->env)
{
if (gsdata->displayCallback)
@@ -173,7 +160,9 @@ void callbacks::setDisplayCallback(void *instance, jobject displayCallback)
void callbacks::setCalloutCallback(void *instance, jobject callout)
{
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromInstance(instance);
+ assert(gsdata);
+
if (gsdata->env)
{
if (gsdata->callout)
@@ -187,79 +176,91 @@ int callbacks::calloutFunction(void *instance, void *handle, const char *deviceN
{
int code = 0;
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromInstance(instance);
+ assert(gsdata);
+
if (gsdata->env && gsdata->callout)
{
jsize len = strlen(deviceName);
jbyteArray array = gsdata->env->NewByteArray(len);
gsdata->env->SetByteArrayRegion(array, 0, len, (const jbyte *)deviceName);
- code = callIntMethod(gsdata->env, gsdata->callout, "onCallout", "(JJ[BIIJ)I", (jlong)instance, (jlong)handle, array, id, size, (jlong)data);
+ code = callIntMethod(gsdata->env, gsdata->callout, "onCallout", "(JJ[BIIJ)I", (jlong)instance, (jlong)gsdata->callerHandle, array, id, size, (jlong)data);
}
return code;
}
-int callbacks::display::displayOpenFunction(void *instance, void *handle, void *device)
+int callbacks::display::displayOpenFunction(void *handle, void *device)
{
int code = 0;
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromHandle(handle);
+ assert(gsdata);
+
if (gsdata->env && gsdata->displayCallback)
{
jclass clazz = gsdata->env->GetObjectClass(gsdata->displayCallback);
const char *name = getClassName(gsdata->env, clazz);
freeClassName(name);
- code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayOpen", DISPLAY_OPEN_SIG, (jlong)handle, (jlong)device);
+ code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayOpen", DISPLAY_OPEN_SIG, (jlong)gsdata->callerHandle, (jlong)device);
CHECK_AND_RETURN(gsdata->env);
}
return code;
}
-int callbacks::display::displayPrecloseFunction(void *instance, void *handle, void *device)
+int callbacks::display::displayPrecloseFunction(void *handle, void *device)
{
int code = 0;
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromHandle(handle);
+ assert(gsdata);
+
if (gsdata->env && gsdata->displayCallback)
{
- code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayPreclose", DISPLAY_PRECLOSE_SIG, (jlong)handle, (jlong)device);
+ code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayPreclose", DISPLAY_PRECLOSE_SIG, (jlong)gsdata->callerHandle, (jlong)device);
CHECK_AND_RETURN(gsdata->env);
}
return code;
}
-int callbacks::display::displayCloseFunction(void *instance, void *handle, void *device)
+int callbacks::display::displayCloseFunction(void *handle, void *device)
{
int code = 0;
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromHandle(handle);
+ assert(gsdata);
+
if (gsdata->env && gsdata->displayCallback)
{
- code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayClose", DISPLAY_CLOSE_SIG, (jlong)handle, (jlong)device);
+ code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayClose", DISPLAY_CLOSE_SIG, (jlong)gsdata->callerHandle, (jlong)device);
CHECK_AND_RETURN(gsdata->env);
}
return code;
}
-int callbacks::display::displayPresizeFunction(void *instance, void *handle, void *device, int width, int height, int raster, unsigned int format)
+int callbacks::display::displayPresizeFunction(void *handle, void *device, int width, int height, int raster, unsigned int format)
{
int code = 0;
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromHandle(handle);
+ assert(gsdata);
+
if (gsdata->env && gsdata->displayCallback)
{
- code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayPresize", DISPLAY_PRESIZE_SIG, (jlong)handle,
+ code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayPresize", DISPLAY_PRESIZE_SIG, (jlong)gsdata->callerHandle,
(jlong)device, width, height, raster, (jint)format);
CHECK_AND_RETURN(gsdata->env);
}
return code;
}
-int callbacks::display::displaySizeFunction(void *instance, void *handle, void *device, int width, int height, int raster,
+int callbacks::display::displaySizeFunction(void *handle, void *device, int width, int height, int raster,
unsigned int format, unsigned char *pimage)
{
int code = 0;
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromHandle(handle);
+ assert(gsdata);
+
if (gsdata->env && gsdata->displayCallback)
{
jsize len = height * raster;
@@ -308,92 +309,104 @@ int callbacks::display::displaySizeFunction(void *instance, void *handle, void *
gsdata->env->SetLongField(bytePointer, dataPtrID, (jlong)pimage);
gsdata->env->SetLongField(bytePointer, lengthID, len);
- code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplaySize", DISPLAY_SIZE_SIG, (jlong)handle,
+ code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplaySize", DISPLAY_SIZE_SIG, (jlong)gsdata->callerHandle,
(jlong)device, width, height, raster, (jint)format, bytePointer);
CHECK_AND_RETURN(gsdata->env);
}
return code;
}
-int callbacks::display::displaySyncFunction(void *instance, void *handle, void *device)
+int callbacks::display::displaySyncFunction(void *handle, void *device)
{
int code = 0;
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromHandle(handle);
+ assert(gsdata);
+
if (gsdata->env && gsdata->displayCallback)
{
- code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplaySync", DISPLAY_SYNC_SIG, (jlong)handle, (jlong)device);
+ code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplaySync", DISPLAY_SYNC_SIG, (jlong)gsdata->callerHandle, (jlong)device);
CHECK_AND_RETURN(gsdata->env);
}
return code;
}
-int callbacks::display::displayPageFunction(void *instance, void *handle, void *device, int copies, int flush)
+int callbacks::display::displayPageFunction(void *handle, void *device, int copies, int flush)
{
int code = 0;
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromHandle(handle);
+ assert(gsdata);
+
if (gsdata->env && gsdata->displayCallback)
{
- code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayPage", DISPLAY_PAGE_SIG, (jlong)handle,
+ code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayPage", DISPLAY_PAGE_SIG, (jlong)gsdata->callerHandle,
(jlong)device, copies, flush);
CHECK_AND_RETURN(gsdata->env);
}
return code;
}
-int callbacks::display::displayUpdateFunction(void *instance, void *handle, void *device, int x, int y, int w, int h)
+int callbacks::display::displayUpdateFunction(void *handle, void *device, int x, int y, int w, int h)
{
int code = 0;
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromHandle(handle);
+ assert(gsdata);
+
if (gsdata->env && gsdata->displayCallback)
{
- code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayUpdate", DISPLAY_UPDATE_SIG, (jlong)handle,
+ code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayUpdate", DISPLAY_UPDATE_SIG, (jlong)gsdata->callerHandle,
(jlong)device, x, y, w, h);
CHECK_AND_RETURN(gsdata->env);
}
return code;
}
-int callbacks::display::displaySeparationFunction(void *instance, void *handle, void *device, int component, const char *componentName,
+int callbacks::display::displaySeparationFunction(void *handle, void *device, int component, const char *componentName,
unsigned short c, unsigned short m, unsigned short y, unsigned short k)
{
int code = 0;
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromHandle(handle);
+ assert(gsdata);
+
if (gsdata->env && gsdata->displayCallback)
{
jsize len = strlen(componentName);
jbyteArray byteArray = gsdata->env->NewByteArray(len);
gsdata->env->SetByteArrayRegion(byteArray, 0, len, (const jbyte *)componentName);
- code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplaySeparation", DISPLAY_SEPARATION_SIG, (jlong)handle,
+ code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplaySeparation", DISPLAY_SEPARATION_SIG, (jlong)gsdata->callerHandle,
(jlong)device, component, byteArray, c, m, y, k);
CHECK_AND_RETURN(gsdata->env);
}
return code;
}
-int callbacks::display::displayAdjustBandHeightFunction(void *instance, void *handle, void *device, int bandHeight)
+int callbacks::display::displayAdjustBandHeightFunction(void *handle, void *device, int bandHeight)
{
int code = 0;
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromHandle(handle);
+ assert(gsdata);
+
if (gsdata->env && gsdata->displayCallback)
{
code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayAdjustBandHeght", DISPLAY_ADJUST_BAND_HEIGHT_SIG,
- (jlong)handle, (jlong)device, bandHeight);
+ (jlong)gsdata->callerHandle, (jlong)device, bandHeight);
CHECK_AND_RETURN(gsdata->env);
}
return code;
}
-int callbacks::display::displayRectangleRequestFunction(void *instance, void *handle, void *device, void **memory, int *ox, int *oy,
+int callbacks::display::displayRectangleRequestFunction(void *handle, void *device, void **memory, int *ox, int *oy,
int *raster, int *plane_raster, int *x, int *y, int *w, int *h)
{
int code = 0;
- GSInstanceData *gsdata = getInstanceData(instance);
+ GSInstanceData *gsdata = findDataFromHandle(handle);
+ assert(gsdata);
+
if (gsdata->env && gsdata->displayCallback)
{
Reference memoryRef = Reference(gsdata->env, toWrapperType(gsdata->env, (jlong)*memory));
@@ -407,7 +420,7 @@ int callbacks::display::displayRectangleRequestFunction(void *instance, void *ha
Reference hRef = Reference(gsdata->env, toWrapperType(gsdata->env, (jint)*h));
code = callIntMethod(gsdata->env, gsdata->displayCallback, "onDisplayRectangleRequest", DISPLAY_RECTANGLE_REQUEST,
- (jlong)handle,
+ (jlong)gsdata->callerHandle,
(jlong)device,
memoryRef.object(),
oxRef.object(),
diff --git a/demos/java/jni/gs_jni/callbacks.h b/demos/java/jni/gs_jni/callbacks.h
index 93a3c5f3f..f2a6bc75a 100644
--- a/demos/java/jni/gs_jni/callbacks.h
+++ b/demos/java/jni/gs_jni/callbacks.h
@@ -18,33 +18,33 @@ namespace callbacks
int stdErrFunction(void *callerHandle, const char *str, int len);
void setPollCallback(void *instance, jobject poll);
- int pollFunction(void *instance, void *callerHandle);
+ int pollFunction(void *callerHandle);
void setDisplayCallback(void *instance, jobject displayCallback);
namespace display
{
- int displayOpenFunction(void *instance, void *handle, void *device);
- int displayPrecloseFunction(void *instance, void *handle, void *device);
- int displayCloseFunction(void *instance, void *handle, void *device);
- int displayPresizeFunction(void *instance, void *handle, void *device, int width,
+ int displayOpenFunction(void *handle, void *device);
+ int displayPrecloseFunction(void *handle, void *device);
+ int displayCloseFunction(void *handle, void *device);
+ int displayPresizeFunction(void *handle, void *device, int width,
int height, int raster, unsigned int format);
- int displaySizeFunction(void *instance, void *handle, void *device, int width,
+ int displaySizeFunction(void *handle, void *device, int width,
int height, int raster, unsigned int format,
unsigned char *pimage);
- int displaySyncFunction(void *instance, void *handle, void *device);
- int displayPageFunction(void *instance, void *handle, void *device, int copies,
+ int displaySyncFunction(void *handle, void *device);
+ int displayPageFunction(void *handle, void *device, int copies,
int flush);
- int displayUpdateFunction(void *instance, void *handle, void *device, int x,
+ int displayUpdateFunction(void *handle, void *device, int x,
int y, int w, int h);
// display_memalloc omitted
// display_memfree omitted
- int displaySeparationFunction(void *instance, void *handle, void *device,
+ int displaySeparationFunction(void *handle, void *device,
int component, const char *componentName, unsigned short c,
unsigned short m, unsigned short y, unsigned short k);
- int displayAdjustBandHeightFunction(void *instance, void *handle, void *device,
+ int displayAdjustBandHeightFunction(void *handle, void *device,
int bandHeight);
- int displayRectangleRequestFunction(void *instance, void *handle, void *device,
+ int displayRectangleRequestFunction(void *handle, void *device,
void **memory, int *ox, int *oy, int *raster, int *plane_raster,
int *x, int *y, int *w, int *h);
}
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 b28334e9b..db39d3725 100644
--- a/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp
+++ b/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp
@@ -7,6 +7,7 @@
#include "jni_util.h"
#include "callbacks.h"
+#include "instance_data.h"
using namespace util;
@@ -35,18 +36,26 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1new_1instance
if (instance == NULL)
return throwNullPointerException(env, "LongReference object is NULL");
+ GSInstanceData *idata = new GSInstanceData();
+ idata->callerHandle = (void *)callerHandle;
+
void *gsInstance;
- int code = gsapi_new_instance(&gsInstance, (void *)callerHandle);
+ int code = gsapi_new_instance(&gsInstance, idata);
if (code == 0)
Reference::setValueField(env, instance, toWrapperType(env, (jlong)gsInstance));
+
+ idata->instance = gsInstance;
+
return code;
}
JNIEXPORT void JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1delete_1instance
(JNIEnv *env, jclass, jlong instance)
{
- callbacks::setJNIEnv(env);
+ callbacks::setJNIEnv((void *)instance, env);
gsapi_delete_instance((void *)instance);
+
+ deleteDataFromInstance((void *)instance);
}
JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1stdio_1with_1handle
@@ -56,8 +65,8 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1stdio_1with_1ha
callbacks::stdOutFunction, callbacks::stdErrFunction, (void *)callerHandle);
if (code == 0)
{
- callbacks::setJNIEnv(env);
- callbacks::setIOCallbacks(stdIn, stdOut, stdErr);
+ callbacks::setJNIEnv((void *)instance, env);
+ callbacks::setIOCallbacks((void *)instance, stdIn, stdOut, stdErr);
}
return code;
}
@@ -69,8 +78,8 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1stdio
callbacks::stdOutFunction, callbacks::stdErrFunction);
if (code == 0)
{
- callbacks::setJNIEnv(env);
- callbacks::setIOCallbacks(stdIn, stdOut, stdErr);
+ callbacks::setJNIEnv((void *)instance, env);
+ callbacks::setIOCallbacks((void *)instance, stdIn, stdOut, stdErr);
}
return code;
}
@@ -81,8 +90,8 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1poll_1with_1han
int code = gsapi_set_poll_with_handle((void *)instance, callbacks::pollFunction, (void *)callerHandle);
if (code == 0)
{
- callbacks::setJNIEnv(env);
- callbacks::setPollCallback(poll);
+ callbacks::setJNIEnv((void *)instance, env);
+ callbacks::setPollCallback((void *)instance, poll);
}
return code;
}
@@ -93,8 +102,8 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1poll
int code = gsapi_set_poll((void *)instance, callbacks::pollFunction);
if (code == 0)
{
- callbacks::setJNIEnv(env);
- callbacks::setPollCallback(poll);
+ callbacks::setJNIEnv((void *)instance, env);
+ callbacks::setPollCallback((void *)instance, poll);
}
return code;
}
@@ -124,8 +133,8 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1display_1callba
int code = gsapi_set_display_callback((void *)instance, cb);
if (code == 0)
{
- callbacks::setJNIEnv(env);
- callbacks::setDisplayCallback(displayCallback);
+ callbacks::setJNIEnv((void *)instance, env);
+ callbacks::setDisplayCallback((void *)instance, displayCallback);
}
return code;
}
@@ -136,8 +145,8 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1register_1callout
int code = gsapi_register_callout((void *)instance, callbacks::calloutFunction, (void *)calloutHandle);
if (code == 0)
{
- callbacks::setJNIEnv(env);
- callbacks::setCalloutCallback(callout);
+ callbacks::setJNIEnv((void *)instance, env);
+ callbacks::setCalloutCallback((void *)instance, callout);
}
return code;
}
@@ -160,7 +169,7 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1default_1device
if (list == NULL)
return throwNullPointerException(env, "list");
jboolean isCopy = false;
- callbacks::setJNIEnv(env);
+ callbacks::setJNIEnv((void *)instance, env);
int code = gsapi_set_default_device_list((void *)instance,
(const char *)env->GetByteArrayElements(list, &isCopy), listlen);
return code;
@@ -193,7 +202,7 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1init_1with_1args
if (argv == NULL)
return throwNullPointerException(env, "argv");
char **cargv = jbyteArray2DToCharArray(env, argv);
- callbacks::setJNIEnv(env);
+ callbacks::setJNIEnv((void *)instance, env);
int code = gsapi_init_with_args((void *)instance, argc, cargv);
delete2DByteArray(argc, cargv);
return code;
@@ -203,7 +212,7 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1begin
(JNIEnv *env, jclass, jlong instance, jint userErrors, jobject pExitCode)
{
int exitCode;
- callbacks::setJNIEnv(env);
+ callbacks::setJNIEnv((void *)instance, env);
int code = gsapi_run_string_begin((void *)instance, userErrors, &exitCode);
if (pExitCode)
Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode));
@@ -218,7 +227,7 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1continu
jboolean copy = false;
int exitCode;
const char *cstring = (const char *)env->GetByteArrayElements(str, &copy);
- callbacks::setJNIEnv(env);
+ callbacks::setJNIEnv((void *)instance, env);
int code = gsapi_run_string_continue((void *)instance, cstring, length, userErrors, &exitCode);
if (pExitCode)
Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode));
@@ -229,7 +238,7 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1end
(JNIEnv *env, jclass, jlong instance, jint userErrors, jobject pExitCode)
{
int exitCode;
- callbacks::setJNIEnv(env);
+ callbacks::setJNIEnv((void *)instance, env);
int code = gsapi_run_string_end((void *)instance, userErrors, &exitCode);
if (pExitCode)
Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode));
@@ -244,7 +253,7 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1with_1l
jboolean copy = false;
int exitCode;
const char *cstring = (const char *)env->GetByteArrayElements(str, &copy);
- callbacks::setJNIEnv(env);
+ callbacks::setJNIEnv((void *)instance, env);
int code = gsapi_run_string_with_length((void *)instance, cstring, length, userErrors, &exitCode);
if (pExitCode)
Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode));
@@ -259,7 +268,7 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string
jboolean copy = false;
int exitCode;
const char *cstring = (const char *)env->GetByteArrayElements(str, &copy);
- callbacks::setJNIEnv(env);
+ callbacks::setJNIEnv((void *)instance, env);
int code = gsapi_run_string((void *)instance, cstring, userErrors, &exitCode);
if (pExitCode)
Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode));
@@ -274,7 +283,7 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1file
jboolean copy = false;
int exitCode;
const char *cstring = (const char *)env->GetByteArrayElements(fileName, &copy);
- callbacks::setJNIEnv(env);
+ callbacks::setJNIEnv((void *)instance, env);
int code = gsapi_run_file((void *)instance, cstring, userErrors, &exitCode);
if (pExitCode)
Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode));
@@ -308,7 +317,7 @@ JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1param
jboolean copy = false;
const char *cstring = (const char *)env->GetByteArrayElements(param, &copy);
- callbacks::setJNIEnv(env);
+ callbacks::setJNIEnv((void *)instance, env);
int code = gsapi_set_param((void *)instance, cstring, data, type);
free(data);
diff --git a/demos/java/jni/gs_jni/gs_jni.vcxproj b/demos/java/jni/gs_jni/gs_jni.vcxproj
index 5febb0d26..369670fc3 100644
--- a/demos/java/jni/gs_jni/gs_jni.vcxproj
+++ b/demos/java/jni/gs_jni/gs_jni.vcxproj
@@ -169,6 +169,7 @@
<ClInclude Include="com_artifex_gsjava_GSAPI.h" />
<ClInclude Include="com_artifex_gsjava_util_NativePointer.h" />
<ClInclude Include="framework.h" />
+ <ClInclude Include="instance_data.h" />
<ClInclude Include="jni_util.h" />
</ItemGroup>
<ItemGroup>
@@ -176,6 +177,7 @@
<ClCompile Include="com_artifex_gsjava_GSAPI.cpp" />
<ClCompile Include="com_artifex_gsjava_util_NativePointer.cpp" />
<ClCompile Include="dllmain.cpp" />
+ <ClCompile Include="instance_data.cpp" />
<ClCompile Include="jni_util.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
diff --git a/demos/java/jni/gs_jni/gs_jni.vcxproj.filters b/demos/java/jni/gs_jni/gs_jni.vcxproj.filters
index 14063f1b4..c69db33f9 100644
--- a/demos/java/jni/gs_jni/gs_jni.vcxproj.filters
+++ b/demos/java/jni/gs_jni/gs_jni.vcxproj.filters
@@ -30,6 +30,9 @@
<ClInclude Include="com_artifex_gsjava_util_NativePointer.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="instance_data.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
@@ -47,5 +50,8 @@
<ClCompile Include="com_artifex_gsjava_util_NativePointer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="instance_data.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/demos/java/jni/gs_jni/instance_data.cpp b/demos/java/jni/gs_jni/instance_data.cpp
new file mode 100644
index 000000000..ca297328a
--- /dev/null
+++ b/demos/java/jni/gs_jni/instance_data.cpp
@@ -0,0 +1,60 @@
+#include "instance_data.h"
+
+#include <unordered_map>
+
+#include <assert.h>
+
+static std::unordered_map<void *, GSInstanceData *> g_inst2Data; // instance -> data
+static std::unordered_map<void *, GSInstanceData *> g_hand2Data; // caller handle -> data
+
+GSInstanceData *putInstanceData(GSInstanceData *data)
+{
+ 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;
+}
+
+GSInstanceData *findDataFromInstance(void *instance)
+{
+ auto it = g_inst2Data.find(instance);
+ return it == g_inst2Data.end() ? NULL : it->second;
+}
+
+GSInstanceData *findDataFromHandle(void *callerHandle)
+{
+ auto it = g_hand2Data.find(callerHandle);
+ return it == g_hand2Data.end() ? NULL : it->second;
+}
+
+void deleteDataFromInstance(void *instance)
+{
+ auto i2dit = g_inst2Data.find(instance);
+ if (i2dit != g_inst2Data.end())
+ {
+ GSInstanceData *idata = i2dit->second;
+ auto h2dit = g_hand2Data.find(idata->callerHandle);
+
+ assert(h2dit != g_hand2Data.end());
+
+ g_inst2Data.erase(i2dit);
+ g_hand2Data.erase(h2dit);
+ }
+}
+
+void deleteDataFromHandle(void *callerHandle)
+{
+ auto h2dit = g_hand2Data.find(callerHandle);
+ if (h2dit != g_hand2Data.end())
+ {
+ GSInstanceData *idata = h2dit->second;
+ auto i2dit = g_inst2Data.find(idata->instance);
+
+ assert(i2dit != g_inst2Data.end());
+
+ g_hand2Data.erase(i2dit);
+ g_inst2Data.erase(h2dit);
+ }
+}
diff --git a/demos/java/jni/gs_jni/instance_data.h b/demos/java/jni/gs_jni/instance_data.h
new file mode 100644
index 000000000..2405e128e
--- /dev/null
+++ b/demos/java/jni/gs_jni/instance_data.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <jni.h>
+
+class GSInstanceData
+{
+public:
+ void *instance = NULL;
+ void *callerHandle = NULL;
+
+ JNIEnv *env;
+
+ jobject stdIn = NULL;
+ jobject stdOut = NULL;
+ jobject stdErr = NULL;
+
+ jobject poll = NULL;
+
+ jobject displayCallback = NULL;
+
+ jobject callout = NULL;
+};
+
+GSInstanceData *putInstanceData(GSInstanceData *data);
+GSInstanceData *findDataFromInstance(void *instance);
+GSInstanceData *findDataFromHandle(void *callerHandle);
+void deleteDataFromInstance(void *instance);
+void deleteDataFromHandle(void *callerHandle); \ No newline at end of file