[Mono-winforms-list] Is System.Drawing (libgdiplus) thread-safe?

Sebastien Pouliot sebastien.pouliot at gmail.com
Wed Oct 28 14:13:52 EDT 2009


On Wed, 2009-10-28 at 19:37 +0200, Alex Shulgin wrote:
> Hi all,
> 
> Is System.Drawing by any means thread-safe?

No, like most of the .net framework, i.e.

        <quote>Any public static (Shared in Visual Basic) members of
        this type are thread safe. Any instance members are not
        guaranteed to be thread safe.</quote>

> 
> Can I create some threads, create a Graphics object in each of them and 
> then work with it from within that thread?  

Yes, you can (or it's a bug). However you also need to make sure you're
not using the Graphic instance (and other created objects) only from a
single (and original) thread.

> Is this supposed to work or 
> am I doing something really stupid here?
> 
> I ask because I've noticed random crashes in a WinForms app on OS X (but 
> it happens on Linux too).  Most of the time it crashes in 
> System.Drawing.Graphics' DrawString or MeasureString methods and seems 
> to occur then a background worker thread is working in parallel with UI 
> thread.
> 
> I've tried to do a stress-test of System.Drawing in a sample 
> multi-threaded program.  See attached `test-multi-threaded-drawing.cs'.

Please open a bug report on bugzilla.novell.com and attach your test
case.

> On my Linux box it crashes all the time.  I get a wide variety of errors 
> from gdb stacktraces with SIGSEGV or SIGABRT in the end, to SIGILL with 
> .Net stack trace.
> 
> Uncommenting these lock {} lines in the ThreadProc helps, but not an 
> option for my real app, as there's simply no single place a lock could 
> be added.
> 
> I've also tried writing some code in plain C which links to libgdiplus 
> directly: see `threads-gdiplus.c'.  It happily crashes just like the C# 
> version.

Most of System.Drawing is only a small wrapper abound libgdiplus (or GDI
+ under Windows). Any bug will likely be inside libgdiplus so it's
"normal" (i.e. expected) that you get the same behavior.

> My tests show that even using unsynchronized GdipGetImageGraphicsContext 
> / GdipDeleteGraphics (no fonts stuff touched) can easily lead to crashes.
> 
>  From what I've seen, cairo seems to be thread-safe: see attached[1] 
> `cairo-multi-thread-text.c'.

It's thread-safe as long as everything is created and executed in the
same thread. Otherwise it would not be safe-thread (just like .net and
most libraries are).

> Also, there's a few locking used around thread-unsafe fontconfig calls 
> in libgdiplus itself.  I didn't examined the whole code, so there's 
> possibly other places in it missing locking primitives.

Yep. Font-related code (and older, pre-1.4, versions of Cairo) had quite
a few problems (solved with the locking code). Other than that SWF and
ASP.NET were the big clients for SD/libgdiplus and, for SWF,
multithreading was not an issue at all.

> I would appreciate any help on this subject!
> 
> --
> Regards,
> Alex
> [1] originally found in the cairo bugzilla for a few-years-old bug; my 
> sligthly enhanced version
> _______________________________________________
> Mono-winforms-list maillist  -  Mono-winforms-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-winforms-list



More information about the Mono-winforms-list mailing list