summaryrefslogtreecommitdiff
path: root/demos
diff options
context:
space:
mode:
authorEthan Vrhel <ethanvrhel@gmail.com>2021-10-30 14:44:37 -0700
committerEthan Vrhel <ethanvrhel@gmail.com>2021-10-30 14:54:31 -0700
commite58eeed4a3716adbc47f65e2ef2f812701f6f450 (patch)
tree0d4d44399ed2a24d7dc9da8711fad5c1affc0c35 /demos
parentee0bbe7e6314c08ff14b60fbf23816da81167318 (diff)
downloadghostpdl-e58eeed4a3716adbc47f65e2ef2f812701f6f450.tar.gz
Added documentation for Java multithreading demo
Diffstat (limited to 'demos')
-rw-r--r--demos/java/jni/gs_jni/instance_data.cpp8
-rw-r--r--demos/java/jni/gs_jni/instance_data.h23
-rw-r--r--demos/java/mtdemo/Main.java21
-rw-r--r--demos/java/mtdemo/README.txt14
-rw-r--r--demos/java/mtdemo/Worker.java24
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;
}