diff options
author | Ethan Vrhel <ethanvrhel@gmail.com> | 2021-10-29 17:08:41 -0700 |
---|---|---|
committer | Ethan Vrhel <ethanvrhel@gmail.com> | 2021-10-29 17:09:08 -0700 |
commit | fd131bd575b1b6f771acf6628744b372c6aa4548 (patch) | |
tree | 831aea4743bbd65b5e3f390ae2d24aa1f87eadf4 /demos | |
parent | ff1882c1e0915d2aad7689ba3c20adb3de64188e (diff) | |
download | ghostpdl-fd131bd575b1b6f771acf6628744b372c6aa4548.tar.gz |
Updating gs_jni to support multithreading
Diffstat (limited to 'demos')
-rw-r--r-- | demos/java/jni/gs_jni/callbacks.cpp | 173 | ||||
-rw-r--r-- | demos/java/jni/gs_jni/callbacks.h | 24 | ||||
-rw-r--r-- | demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp | 55 | ||||
-rw-r--r-- | demos/java/jni/gs_jni/gs_jni.vcxproj | 2 | ||||
-rw-r--r-- | demos/java/jni/gs_jni/gs_jni.vcxproj.filters | 6 | ||||
-rw-r--r-- | demos/java/jni/gs_jni/instance_data.cpp | 60 | ||||
-rw-r--r-- | demos/java/jni/gs_jni/instance_data.h | 28 |
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, ©); - 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, ©); - 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, ©); - 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, ©); - 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, ©); - 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 |