diff options
author | Ethan Vrhel <ethanvrhel@gmail.com> | 2021-10-30 14:44:37 -0700 |
---|---|---|
committer | Ethan Vrhel <ethanvrhel@gmail.com> | 2021-10-30 14:54:31 -0700 |
commit | e58eeed4a3716adbc47f65e2ef2f812701f6f450 (patch) | |
tree | 0d4d44399ed2a24d7dc9da8711fad5c1affc0c35 /demos | |
parent | ee0bbe7e6314c08ff14b60fbf23816da81167318 (diff) | |
download | ghostpdl-e58eeed4a3716adbc47f65e2ef2f812701f6f450.tar.gz |
Added documentation for Java multithreading demo
Diffstat (limited to 'demos')
-rw-r--r-- | demos/java/jni/gs_jni/instance_data.cpp | 8 | ||||
-rw-r--r-- | demos/java/jni/gs_jni/instance_data.h | 23 | ||||
-rw-r--r-- | demos/java/mtdemo/Main.java | 21 | ||||
-rw-r--r-- | demos/java/mtdemo/README.txt | 14 | ||||
-rw-r--r-- | demos/java/mtdemo/Worker.java | 24 |
5 files changed, 60 insertions, 30 deletions
diff --git a/demos/java/jni/gs_jni/instance_data.cpp b/demos/java/jni/gs_jni/instance_data.cpp index 8c9d1a05f..3bf315aee 100644 --- a/demos/java/jni/gs_jni/instance_data.cpp +++ b/demos/java/jni/gs_jni/instance_data.cpp @@ -4,7 +4,7 @@ #include <assert.h> #include <mutex> -#if defined(ALLOW_MT) +#if defined(GSJNI_SUPPORT_MT) static std::unordered_map<void *, GSInstanceData *> g_inst2Data; // instance -> data static std::mutex g_mtx; @@ -17,7 +17,7 @@ static GSInstanceData g_global; // Global instance for faster multithreading GSInstanceData *putInstanceData(GSInstanceData *data) { -#if defined(ALLOW_MT) +#if defined(GSJNI_SUPPORT_MT) g_mtx.lock(); assert(g_inst2Data.find(data->instance) == g_inst2Data.end()); @@ -36,7 +36,7 @@ GSInstanceData *putInstanceData(GSInstanceData *data) GSInstanceData *findDataFromInstance(void *instance) { -#if defined(ALLOW_MT) +#if defined(GSJNI_SUPPORT_MT) g_mtx.lock(); auto it = g_inst2Data.find(instance); @@ -52,7 +52,7 @@ GSInstanceData *findDataFromInstance(void *instance) void deleteDataFromInstance(void *instance) { -#if defined(ALLOW_MT) +#if defined(GSJNI_SUPPORT_MT) g_mtx.lock(); auto i2dit = g_inst2Data.find(instance); diff --git a/demos/java/jni/gs_jni/instance_data.h b/demos/java/jni/gs_jni/instance_data.h index 22770daf4..e955e76ec 100644 --- a/demos/java/jni/gs_jni/instance_data.h +++ b/demos/java/jni/gs_jni/instance_data.h @@ -4,24 +4,27 @@ #include "settings.h" +/* +This class stores data about a Ghostscript instance. +*/ class GSInstanceData { public: - void *instance = NULL; - void *callerHandle = NULL; - void *stdioHandle = NULL; + void *instance = NULL; // The Ghostscript instance + void *callerHandle = NULL; // The caller handle passed to gsapi_new_instance + void *stdioHandle = NULL; // The caller handle passed to gsapi_set_stdio_with_handle - JNIEnv *env; + JNIEnv *env; // The JNIEnv which should be used for JNI API calls - jobject stdIn = NULL; - jobject stdOut = NULL; - jobject stdErr = NULL; + jobject stdIn = NULL; // The user IStdInFunction class for stdin input + jobject stdOut = NULL; // The user IStdOutFunction class for stdout output + jobject stdErr = NULL; // The user IStdErrFunction class for stderr output - jobject poll = NULL; + jobject poll = NULL; // The user IPollFunction class - jobject displayCallback = NULL; + jobject displayCallback = NULL; // The user DisplayCallback class - jobject callout = NULL; + jobject callout = NULL; // The user ICalloutFunction class }; GSInstanceData *putInstanceData(GSInstanceData *data); diff --git a/demos/java/mtdemo/Main.java b/demos/java/mtdemo/Main.java index bd3ef2f54..f91e5f9f8 100644 --- a/demos/java/mtdemo/Main.java +++ b/demos/java/mtdemo/Main.java @@ -4,11 +4,18 @@ import java.io.File; public class Main { + // The file we will read from public static final String INFILE = "../../../examples/tiger.eps"; + // The output directory + public static final String OUTDIR = "pdfout"; + public static void main(String[] args) { + // For multithreading, call this before any GSInstance objects + // are created. GSInstance.setAllowMultithreading(true); + // Parse first command line argument as thread count int workerCount = 10; if (args.length > 0) { try { @@ -16,12 +23,24 @@ public class Main { } catch (NumberFormatException e) { } } + // Create output directory if it doesn't exist + File outdirFile = new File(OUTDIR); + if (outdirFile.exists()) { + if (outdirFile.isFile()) + System.err.println("Output directory exists as a file!"); + } else { + outdirFile.mkdirs(); + } + + Worker[] workers = new Worker[workerCount]; + // Create each worker for (int i = 0; i < workers.length; i++) { - workers[i] = new Worker(INFILE, "pdfout/out" + i + ".pdf"); + workers[i] = new Worker(INFILE, OUTDIR + "/out" + i + ".pdf"); } + // Dispatch each worker System.out.println("Starting workers..."); for (int i = 0; i < workers.length; i++) { workers[i].start(); diff --git a/demos/java/mtdemo/README.txt b/demos/java/mtdemo/README.txt index 661a10e66..e9b745a4e 100644 --- a/demos/java/mtdemo/README.txt +++ b/demos/java/mtdemo/README.txt @@ -8,6 +8,7 @@ What is here? * Main.java - Class containing Java main method * Worker.java - Class which handles concurrently running Ghostscript * build.bat - Builds the Java program +* runmtd.bat - Starts the Java program Needed in this directory to run: @@ -20,13 +21,6 @@ How to run: Windows: The application can be started through the command line through the -command: - -java -cp gsjava.jar;. Main - -OR - -java -cp gsjava.jar;. Main [thread count] - -where [thread count] is the number of threads (and files) which will -be ran/written.
\ No newline at end of file +batch file "runmtd.bat". The batch file takes an optional command +line argument specifying the number of threads to be created. If +specified, it should be an integer grater than 0.
\ No newline at end of file diff --git a/demos/java/mtdemo/Worker.java b/demos/java/mtdemo/Worker.java index 3da333fd0..874eae957 100644 --- a/demos/java/mtdemo/Worker.java +++ b/demos/java/mtdemo/Worker.java @@ -11,15 +11,21 @@ import java.util.Arrays; import static com.artifex.gsjava.GSAPI.*; +/** + * Handles running a separate instance of Ghostscript. + */ public class Worker implements Runnable { + // Whether to use Java-implemented standard input/output public static final boolean USE_CUSTOM_STDIO = true; + + // Whether stdout is enabled (effective only if USE_CUSTOM_STDIO = true) public static final boolean USE_STDOUT = false; - private static int ID = 0; + private static int ID = 0; // Next thread ID - private final File inPS, outPDF; - private final Thread thread; + private final File inPS, outPDF; // Input and output files + private final Thread thread; // The thread running this worker /** * Create a worker thread to convert a postscript file @@ -35,6 +41,9 @@ public class Worker implements Runnable { this.thread.setName("Worker-" + ID++); } + /** + * Starts this worker + */ public void start() { System.out.println("Start: " + thread.getName()); thread.start(); @@ -48,14 +57,17 @@ public class Worker implements Runnable { try { gsInstance = createGSInstance(); + // If we want to use the IO functions StdIO, set them if (USE_CUSTOM_STDIO) { StdIO io = new StdIO(); gsInstance.set_stdio(io, USE_STDOUT ? io : null, io); } + // Create the output file if it doesn't exist if (!outPDF.exists()) outPDF.createNewFile(); + // Ghostscript arguments to use with init_with_args String[] args = { "gs", "-sDEVICE=pdfwrite", @@ -63,6 +75,7 @@ public class Worker implements Runnable { inPS.getPath() }; + // init_with_args will perform all the conversions int code = gsInstance.init_with_args(args); if (code != GS_ERROR_OK) { gsInstance.delete_instance(); @@ -78,6 +91,7 @@ public class Worker implements Runnable { } } + // Creates a new Ghostscript inistance private GSInstance createGSInstance() { GSInstance gsInstance = new GSInstance(); @@ -91,11 +105,11 @@ public class Worker implements Runnable { return gsInstance; } + // Handles standard input/output private static class StdIO implements IStdOutFunction, IStdErrFunction, IStdInFunction { public int onStdOut(long callerHandle, byte[] str, int len) { - //if (USE_STDOUT) - System.out.println(new String(str)); + System.out.println(new String(str)); return len; } |