| #include <glib-object.h> | |
| /* --------------------------------- */ | |
| /* test_object_constructor_singleton */ | |
| typedef GObject MySingletonObject; | |
| typedef GObjectClass MySingletonObjectClass; | |
| GType my_singleton_object_get_type (void); | |
| G_DEFINE_TYPE (MySingletonObject, my_singleton_object, G_TYPE_OBJECT) | |
| static MySingletonObject *singleton; | |
| static void | |
| my_singleton_object_init (MySingletonObject *obj) | |
| { | |
| } | |
| static GObject * | |
| my_singleton_object_constructor (GType type, | |
| guint n_construct_properties, | |
| GObjectConstructParam *construct_params) | |
| { | |
| GObject *object; | |
| if (singleton) | |
| return g_object_ref (singleton); | |
| object = G_OBJECT_CLASS (my_singleton_object_parent_class)-> | |
| constructor (type, n_construct_properties, construct_params); | |
| singleton = (MySingletonObject *)object; | |
| return object; | |
| } | |
| static void | |
| my_singleton_object_finalize (MySingletonObject *obj) | |
| { | |
| singleton = NULL; | |
| G_OBJECT_CLASS (my_singleton_object_parent_class)->finalize (obj); | |
| } | |
| static void | |
| my_singleton_object_class_init (MySingletonObjectClass *klass) | |
| { | |
| GObjectClass *object_class = G_OBJECT_CLASS (klass); | |
| object_class->constructor = my_singleton_object_constructor; | |
| object_class->finalize = my_singleton_object_finalize; | |
| } | |
| static void | |
| test_object_constructor_singleton (void) | |
| { | |
| MySingletonObject *one, *two, *three; | |
| one = g_object_new (my_singleton_object_get_type (), NULL); | |
| g_assert_cmpint (G_OBJECT (one)->ref_count, ==, 1); | |
| two = g_object_new (my_singleton_object_get_type (), NULL); | |
| g_assert (one == two); | |
| g_assert_cmpint (G_OBJECT (two)->ref_count, ==, 2); | |
| three = g_object_new (my_singleton_object_get_type (), NULL); | |
| g_assert (one == three); | |
| g_assert_cmpint (G_OBJECT (three)->ref_count, ==, 3); | |
| g_object_add_weak_pointer (G_OBJECT (one), (gpointer *)&one); | |
| g_object_unref (one); | |
| g_assert (one != NULL); | |
| g_object_unref (three); | |
| g_object_unref (two); | |
| g_assert (one == NULL); | |
| } | |
| /* ----------------------------------- */ | |
| /* test_object_constructor_infanticide */ | |
| typedef GObject MyInfanticideObject; | |
| typedef GObjectClass MyInfanticideObjectClass; | |
| GType my_infanticide_object_get_type (void); | |
| G_DEFINE_TYPE (MyInfanticideObject, my_infanticide_object, G_TYPE_OBJECT) | |
| static void | |
| my_infanticide_object_init (MyInfanticideObject *obj) | |
| { | |
| } | |
| static GObject * | |
| my_infanticide_object_constructor (GType type, | |
| guint n_construct_properties, | |
| GObjectConstructParam *construct_params) | |
| { | |
| GObject *object; | |
| object = G_OBJECT_CLASS (my_infanticide_object_parent_class)-> | |
| constructor (type, n_construct_properties, construct_params); | |
| g_object_unref (object); | |
| return NULL; | |
| } | |
| static void | |
| my_infanticide_object_class_init (MyInfanticideObjectClass *klass) | |
| { | |
| GObjectClass *object_class = G_OBJECT_CLASS (klass); | |
| object_class->constructor = my_infanticide_object_constructor; | |
| } | |
| static void | |
| test_object_constructor_infanticide (void) | |
| { | |
| GObject *obj; | |
| int i; | |
| #ifndef G_ENABLE_DEBUG | |
| g_test_skip ("skip tests that rely on debug-only warnings"); | |
| return; | |
| #endif | |
| g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=661576"); | |
| for (i = 0; i < 1000; i++) | |
| { | |
| g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL, | |
| "*finalized while still in-construction*"); | |
| g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL, | |
| "*Custom constructor*returned NULL*"); | |
| obj = g_object_new (my_infanticide_object_get_type (), NULL); | |
| g_assert_null (obj); | |
| g_test_assert_expected_messages (); | |
| } | |
| } | |
| /* --------------------------------- */ | |
| int | |
| main (int argc, char *argv[]) | |
| { | |
| g_test_init (&argc, &argv, NULL); | |
| g_test_add_func ("/object/constructor/singleton", test_object_constructor_singleton); | |
| g_test_add_func ("/object/constructor/infanticide", test_object_constructor_infanticide); | |
| return g_test_run (); | |
| } |