Re: Multithreading with GM
Bob Friesenhahn <[email protected]> Tue, 11 Oct 2011 23:53:45 -0500 (CDT)
| Newsgroups | gmane.comp.video.graphicsmagick.bugs |
|---|---|
| Message-ID | <[email protected]> |
On Tue, 11 Oct 2011, Chris Healer wrote: > > The problem I'm having is that no combination of Mutexes seems to > protect the image cache from flushing unpredictably. As an example, there > may be 8 or more threads trying to call something like: > > Pixels view(img); > const PixelPacket *pixels = view.getConst(0,row,img.columns(),1); The Pixels view is just a handle to a heap-allocated structure. It does not maintain a reference count to ensure that the underlying image is not destroyed if there are still allocated views. If the underlying pixel cache is destroyed, then it is important not to use any still-allocated pixel view handles since bad things would surely happen. It is wise to scope/order things so that allocated views are released before the referenced image. In other words, deallocation should be in reverse order of allocation. Besides the Image reference counting that the Magick++ Image class does, the underlying Image structure uses reference counting to the pixel cache representation which actually stores the pixels. Both of these forms of reference counting are designed to be thread safe. > concurrently. It works fine for a while but eventually it crashes. > Running with MAGIC_DEBUG=all reveals: > > destroy cache [path] This message comes right before: cache_info->signature=0; MagickFreeMemory(cache_info); > Destroy blob, image=0x10282b200, filename="[path]" The blob is a structure referenced by the Image. This one is also reference counted. I believe that a bug was fixed which sometimes broke the blob reference counting since the last release. > are reliably the culprits, and: > > Assertion failed: (image->signature == MagickSignature), function > OpenCacheView, file magick/pixel_cache.c, line 3193. This particular assertion would happen if the underlying C API Image structure was already deallocated (or corrupted somehow) when the cache view was opened. > This makes sense... anyone know of a way to control the flushing, or create > a mutex of some kind so I can grant permission for the cache to do its thing? > I can't seem to find anything in the documentation like this... The cache is not destroyed until all of the Image references are gone. There is nothing similar to garbage collection used. Multithreaded programming takes more discipline than normal programming. While you reported an error with OpenCacheView(), I do think that you need to check to make sure that all Pixel view references to an image are destroyed before the referenced Image. It is certainly possible that Magick++ or GraphicsMagick has a bug. Make sure that your build only disabled OpenMP and not the thread locking support. What GraphicsMagick version are you using? If your system is able to run valgrind (does support AMD64/Darwin) then its 'helgrind' tool (and 'drd' tool) can be very useful to discover any locking bugs. As delivered, the development version of GraphicsMagick completely passes the valgrind 'memcheck' and 'helgrind' tests when driven by OpenMP. See "http://www.valgrind.org/" for valgrind. Bob -- Bob Friesenhahn [email protected], http://www.simplesystems.org/users/bfriesen/ GraphicsMagick Maintainer, http://www.GraphicsMagick.org/ ------------------------------------------------------------------------------ All the data continuously generated in your IT infrastructure contains a definitive record of customers, application performance, security threats, fraudulent activity and more. Splunk takes this data and makes sense of it. Business sense. IT sense. Common sense. http://p.sf.net/sfu/splunk-d2d-oct