GNOME Bugzilla – Bug 300659
most object that derivate from gobject are not thread-safe
Last modified: 2005-04-14 21:34:32 UTC
Steps to reproduce: most data types that derivate from g_object are implemented this way : static GType foo_get_type (void) { static GType iface_type = 0; if (!iface_type) { /* block (1) */ static const GTypeInfo iface_info = { ... }; iface_type = g_type_register_static (G_TYPE_INTERFACE, "foo", &iface_info, 0); } return iface_type; } creation of the object is called with : g_object_new(foo_get_type()) that means that if two objects are created at the same time, in two different threads, they can enter both in the block (1), so that, they will both call g_type_register_static() and an assert() can raise when this function is called twice for the same object. using testcommon.h in the example of glib / gobject, I wrote the following : #include <pthread.h> #include <string.h> #include <glib-object.h> #include "testcommon.h" #include <stdio.h> #include <gtk/gtk.h> /* * TestObject, a parent class for TestObject */ #define TEST_TYPE_OBJECT (test_object_get_type ()) typedef struct _TestObject TestObject; typedef struct _TestObjectClass TestObjectClass; struct _TestObject { GObject parent_instance; }; struct _TestObjectClass { GObjectClass parent_class; }; static GType test_object_get_type (void); static void test_object_class_init (TestObjectClass *class) { } static DEFINE_TYPE(TestObject, test_object, test_object_class_init, NULL, NULL, G_TYPE_OBJECT) static void * thread(void * data) { unsigned int i; for(i = 0 ; i < 10000 ; i ++) { TestObject *object; object = g_object_newv (TEST_TYPE_OBJECT, 0, NULL); g_object_unref(object); } return NULL; } #define NUM 5 int main(int argc, char *argv[]) { pthread_t thread_id[NUM]; unsigned int i; g_thread_init(NULL); g_type_init(); for(i = 0 ; i < NUM ; i ++) pthread_create(&thread_id[i], NULL, thread, NULL); thread(NULL); for(i = 0 ; i < NUM ; i++) pthread_join(thread_id[i], NULL); return 0; } of course, if I simply allocate and deallocate a GtkWindow or a GtkTreeStore, it will also crash. Stack trace: I can see : GLib-GObject-ERROR **: g_type_plugin_*() invalidly modified type `TestObject' aborting... Aborted (core dumped) or : Segmentation fault (core dumped) Other information: I can workaround the problem by locking whenever I want to allocate a given type of object.
Next time, please search for duplicates before filing bugs. *** This bug has been marked as a duplicate of 65041 ***