Page 1 of 1

Why is Image.write() blocking all threads?

Posted: 2014-03-14T17:01:46-07:00
by josh3736
I'm trying to perform ImageMagick operations on a thread pool (using libuv).

Each worker thread creates its own Magick::Image instance, does some stuff (different image data and options for every request), and eventually calls Image.write(<freshly allocated Magick::Blob>).

I've noticed that every thread does all its work up to the point where write() is called, and then blocks. It looks like each thread's call to write() does not begin to execute until after the last thread's write() returns, and my CPU usage never crosses 12% (8 core machine).

Why is this happening?

Re: Why is Image.write() blocking all threads?

Posted: 2014-03-14T18:15:52-07:00
by magick
Most coders are multi-threaded, a few are not because ImageMagick depends on a delegate library that is not threaded. An example is JPEG. The JPEG library is not threaded so we can only write one JPEG image at a time. The other single threaded image formats are JPEG-2000 and TIFF. Are you writing an image in one of these formats? If not, let us know which format you're writing and we will investigate further.

Re: Why is Image.write() blocking all threads?

Posted: 2014-03-16T11:35:58-07:00
by josh3736
Thanks for the reply. I'm taking in BMP images and trying to output PNG.

Re: Why is Image.write() blocking all threads?

Posted: 2014-03-16T11:47:32-07:00
by dlemstra
The png coder uses 'SETJMP_IS_THREAD_SAFE' to determine if it needs a lock. What is your operating system?

Re: Why is Image.write() blocking all threads?

Posted: 2014-03-16T11:59:55-07:00
by josh3736
Windows 8.1

Re: Why is Image.write() blocking all threads?

Posted: 2014-03-16T14:25:20-07:00
by glennrp
dlemstra wrote:The png coder uses 'SETJMP_IS_THREAD_SAFE' to determine if it needs a lock. What is your operating system?
Years ago allegations were made to the PNG developers that some operating systems have a setjmp() that is not thread safe. But we've never been told
which setjmp() implementations are thread-safe and which are not, so since then all have been treated as unsafe. The intent was to add
#defines at line 625 in coders/png.c to set SETJMP_IS_THREAD_SAFE for platforms known to be safe.

Re: Why is Image.write() blocking all threads?

Posted: 2014-03-16T14:31:28-07:00
by glennrp
josh3736 wrote:Windows 8.1
Do you know if your libpng uses setjmp()? Libpng does by default, but it can be defined out when you
configure libpng, and we should add a test for PNG_SETJMP_SUPPORTED in coders/png.c
to avoid the blockage.

Re: Why is Image.write() blocking all threads?

Posted: 2014-03-16T15:25:48-07:00
by dlemstra
The Windows distribution of ImageMagick currently uses 1.6.10 and PNG_SETJMP_SUPPORTED is defined. I will have to check if setjmp is thread safe under Windows and define IMPNG_SETJMP_IS_THREAD_SAFE if it is.

Edit: It is safe under Windows and the define has been added.