Is Outside In's PDF Export library's function EXOpenExport thread-safe?

564 views Asked by At

I'm writing a C++ wrapper, for Node.js, around the Oracle Outside In PDF Export library, on Ubuntu Linux. Node.js has a single threaded event loop and therefor any long-running processing is done on a worker thread. So, my wrapper is calling all of the PDF Export methods inside of this worker thread. I mention this so that you can be sure of two things: this is a threaded environment, and all PDF Export functions are being called on the same worker thread. Also, I am not making use of any redirected IO or PDF Export-handled threading. I've initialized the library specifying to use no threads. So all of this processing should be occurring within the thread that I call the functions on.

Everything seems to go fine when exporting a single PDF or even maybe two or three in quick succession. When I up the number of PDFs that I try to export to 5+, I receive a SIGSEGV segmentation fault from within the OIT libs. The back trace is below:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff4fd0700 (LWP 1577)]
0x00007fffeef1da26 in HandlePoolCreateHandle () from /usr/local/lib/pdfexport/libwv_core.so
(gdb) bt
#0  0x00007fffeef1da26 in HandlePoolCreateHandle () from /usr/local/lib/pdfexport/libwv_core.so
#1  0x00007fffeef1925d in Win32VCreateHandle () from /usr/local/lib/pdfexport/libwv_core.so
#2  0x00007fffed49046b in WrapBrush(void*, GdiBrush*) () from /usr/local/lib/pdfexport/libos_pdf.so
#3  0x00007fffed46e8c8 in ?? () from /usr/local/lib/pdfexport/libos_pdf.so
#4  0x00007fffed46df63 in GNGetOutputSolutionInfoAt () from /usr/local/lib/pdfexport/libos_pdf.so
#5  0x00007fffeef1e32a in ?? () from /usr/local/lib/pdfexport/libwv_core.so
#6  0x00007fffeef1e214 in ?? () from /usr/local/lib/pdfexport/libwv_core.so
#7  0x00007fffeef18ed3 in Win32VLoadOS () from /usr/local/lib/pdfexport/libwv_core.so
#8  0x00007fffeddffb24 in VwExportOpen () from /usr/local/lib/pdfexport/libex_pagelayout.so
#9  0x00007ffff4062c4d in FAOpenExport () from /usr/local/lib/pdfexport/libsc_fa.so
#10 0x00007ffff7e53270 in EXOpenExport () from /usr/local/lib/pdfexport/libsc_ex.so
#11 0x00007ffff43c0a4d in topdf_convert(uv_work_s*) ()
   from /home/ryan/repos/pdf-service/node_modules/topdf/build/Release/topdf.node
#12 0x00000000006e2ec7 in worker (arg=<optimized out>) at ../deps/uv/src/unix/threadpool.c:65
#13 0x00007ffff6fa6e9a in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0
#14 0x00007ffff6cd3cbd in clone () from /lib/x86_64-linux-gnu/libc.so.6
#15 0x0000000000000000 in ?? ()

I'll explain the back trace a little. The function on #11 is the function inside my code. That is the function in which I call all of the OIT lib functions. The functions on lines #12 and higher are the Node.js-related threading functions, setting up the thread to run my code's function. Functions on lines #10 down to #1 are all the OIT-called functions.

In the documentation for PDF Export, it says that if you're going to be using this library inside a threaded environment, then you need to call the init and deinit functions each time within the worker thread. I'm doing this in my code, which you can see here: https://github.com/ryancole/topdf/blob/master/src/topdf.cc#L29-L74

Is there anything else that I need to be setting that would cause this? I'm only specifying the font directory, explicitly. Are these libraries actually thread-safe? It doesn't look like they are.

1

There are 1 answers

3
Yahia On BEST ANSWER

According to Oracle Outside In V 8.4.0 documentation (Chapter 4.2, page 50) your call to DAInitEx is wrong, check the first param...

DAInitEx should only be called once per application, at application startup time. Any number of documents can be opened for access between calls to DAInitEx and DADeInit. If DAInitEx succeeds, DADeInit must be called regardless of any other API calls.

and

Multiple threads are supported for all Windows platforms and the 32-bit versions of Linux x86 and Solaris SPARC. Failed initialization of the threading function will not impair other API calls. If threading isn't initialized or fails, stub functions are called instead of mutex functions.