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

Sebastien Pouliot <[email protected]>
Newsgroups gmane.comp.gnome.mono.devel,gmane.comp.gnome.winforms
Message-ID <[email protected]>
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  -  [email protected]
> http://lists.ximian.com/mailman/listinfo/mono-winforms-list
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.