All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
implied.
This software is distributed under license and may not be copied,
modified or distributed except as expressly authorized under the terms
of the license contained in the file LICENSE in this distribution.
Refer to licensing information at http://www.artifex.com or contact
Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
CA 94129, USA, for further information.
*/
* the ghostscript/GPDL library. */
#ifdef _WIN32
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#define WINDOWS
#else
#include <pthread.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <assert.h>
#include <limits.h>
#include <stdarg.h>
#include <stdint.h>
* library. The code is the same for both. */
#if GHOSTPDL
#include "pcl/pl/plapi.h"
#else
#include "psi/iapi.h"
#endif
* structure. */
typedef struct
{
int thread_num;
char *in_file;
#ifdef WINDOWS
HANDLE thread;
#else
pthread_t thread;
#endif
int code;
} thread_data;
* Starts a gs instance, runs a file, shuts it down.
*/
static
#ifdef WINDOWS
DWORD WINAPI
#else
void *
#endif
worker(void *td_)
{
thread_data *td = (thread_data *)td_;
int code;
void *instance = NULL;
char out[32];
int argc = 0;
char *argv[10];
sprintf(out, "multi_out_%d_", td->thread_num);
strcat(out, "%d.png");
argv[argc++] = "gpdl";
argv[argc++] = "-sDEVICE=png16m";
argv[argc++] = "-o";
argv[argc++] = out;
argv[argc++] = "-r100";
argv[argc++] = td->in_file;
code = gsapi_new_instance(&instance, NULL);
if (code < 0) {
printf("Error %d in gsapi_new_instance\n", code);
goto failearly;
}
code = gsapi_init_with_args(instance, argc, argv);
if (code < 0) {
printf("Error %d in gsapi_init_with_args\n", code);
goto fail;
}
code = gsapi_exit(instance);
if (code < 0) {
printf("Error %d in gsapi_exit\n", code);
goto fail;
}
fail:
gsapi_delete_instance(instance);
failearly:
td->code = code;
#ifdef WINDOWS
return 0;
#else
return NULL;
#endif
}
char *in_files[] =
{
"../../examples/tiger.eps",
"../../examples/golfer.eps",
"../../examples/escher.ps",
"../../examples/snowflak.ps"
#ifdef GHOSTPDL
, "../../pcl/examples/grashopp.pcl"
, "../../pcl/examples/owl.pcl"
, "../../pcl/examples/tiger.xps"
#endif
};
#define NUM_INPUTS (sizeof(in_files)/sizeof(*in_files))
#define NUM_WORKERS (10)
int main(int argc, char *argv[])
{
int failed = 0;
#ifndef WINDOWS
int code;
#endif
int i;
thread_data td[NUM_WORKERS];
for (i = 0; i < NUM_WORKERS; i++)
{
td[i].in_file = in_files[i % NUM_INPUTS];
td[i].thread_num = i;
#ifdef WINDOWS
td[i].thread = CreateThread(NULL, 0, worker, &td[i], 0, NULL);
#else
code = pthread_create(&td[i].thread, NULL, worker, &td[i]);
if (code != 0) {
fprintf(stderr, "Thread %d creation failed\n", i);
exit(1);
}
#endif
}
for (i = 0; i < NUM_WORKERS; i++)
{
void *status = NULL;
#ifdef WINDOWS
WaitForSingleObject(td[i].thread, INFINITE);
#else
code = pthread_join(td[i].thread, &status);
if (code != 0) {
fprintf(stderr, "Thread join %d failed\n", i);
exit(1);
}
#endif
if (td[i].code != 0)
failed = 1;
fprintf(stderr, "Thread %d finished with %d\n", i, td[i].code);
}
return failed;
}