After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 587892 - [PATCH] Race in GType when instantiating the same class for the first time from multiple threads.
[PATCH] Race in GType when instantiating the same class for the first time fr...
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: gobject
unspecified
Other All
: Normal critical
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2009-07-06 13:51 UTC by Håvard Graff (hgr)
Modified: 2009-12-01 08:01 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Proposed fix by Benjamin Otte (Company) (997 bytes, patch)
2009-07-06 13:53 UTC, Håvard Graff (hgr)
reviewed Details | Review
Test case that easily reproduces the issue (2.31 KB, text/plain)
2009-07-06 13:57 UTC, Håvard Graff (hgr)
  Details

Description Håvard Graff (hgr) 2009-07-06 13:51:29 UTC
Steps to reproduce:
The problem is that the g_type_class_peek function may return a GTypeClass not yet fully initialized, (class_init()  has not yet been called or finished executing) meaning it might call virtual methods on the base class instead of the derived class (like GObjectClass::constructor(), making the object not construct properly).

The fix is to let g_type_class_peek make sure the class is fully constructed (checking that class.init_state == INITIALIZED), since this flag is only set when the GTypeClass has been fully initialized.

The only possible side-effects of this fix would be if g_type_class_peek were called inside the class_init(), it would return NULL, and if some implementation expects this to not fail, this patch will break that.

However, it does not quite make sense that a class should be ready for "peeking" while it is still under construction, so the fix should be safe.

See test case to be attached.

Stack trace:


Other information:
Comment 1 Håvard Graff (hgr) 2009-07-06 13:53:12 UTC
Created attachment 137920 [details] [review]
Proposed fix by Benjamin Otte (Company)
Comment 2 Håvard Graff (hgr) 2009-07-06 13:57:33 UTC
Created attachment 137921 [details]
Test case that easily reproduces the issue

What we do here is to construct the object type from 4 different threads more or less at the same time, but add a little sleep inside the class_init(), making the race more likely to occur.
Comment 3 Matthias Clasen 2009-07-10 16:06:06 UTC
The patch makes a lot of sense to me. Tim, do you agree that this is correct ?

Thanks for the testcase. It would be nice to have a patch that integrates the testcase in gobject/tests/Makefile.am. 
Comment 4 Tim Janik 2009-10-06 13:57:17 UTC
(In reply to comment #0)
> The only possible side-effects of this fix would be if g_type_class_peek were
> called inside the class_init(), it would return NULL, and if some
> implementation expects this to not fail, this patch will break that.

Unfortunately, this is exactly the use case that the current code means to still support. Mostly for backward compatibility reasons. IIRC, when GType was written, old GtkType code did peek classes during construction, so gtype.c was written to support this. I  don't have a concrete usage case in mind atm though.
Comment 5 Benjamin Otte (Company) 2009-12-01 08:01:28 UTC
I believe this has been fixed by the gobject-performance merge. If it turns out there are cases where we need to support peeking during construction, then we have to allow that but get rid of using g_type_class_peek_static() in g_object_new() and use g_type_class_ref() unconditionally - that should not be a big performance hit with the patches merged.