(root)/
glib-2.79.0/
gobject/
tests/
object.c
       1  #include <glib-object.h>
       2  
       3  /* --------------------------------- */
       4  /* test_object_constructor_singleton */
       5  
       6  typedef GObject MySingletonObject;
       7  typedef GObjectClass MySingletonObjectClass;
       8  
       9  GType my_singleton_object_get_type (void);
      10  
      11  G_DEFINE_TYPE (MySingletonObject, my_singleton_object, G_TYPE_OBJECT)
      12  
      13  static MySingletonObject *singleton;
      14  
      15  static void
      16  my_singleton_object_init (MySingletonObject *obj)
      17  {
      18  }
      19  
      20  static GObject *
      21  my_singleton_object_constructor (GType                  type,
      22                                   guint                  n_construct_properties,
      23                                   GObjectConstructParam *construct_params)
      24  {
      25    GObject *object;
      26  
      27    if (singleton)
      28      return g_object_ref (singleton);
      29  
      30    object = G_OBJECT_CLASS (my_singleton_object_parent_class)->
      31      constructor (type, n_construct_properties, construct_params);
      32    singleton = (MySingletonObject *)object;
      33  
      34    return object;
      35  }
      36  
      37  static void
      38  my_singleton_object_finalize (MySingletonObject *obj)
      39  {
      40    singleton = NULL;
      41  
      42    G_OBJECT_CLASS (my_singleton_object_parent_class)->finalize (obj);
      43  }
      44  
      45  static void
      46  my_singleton_object_class_init (MySingletonObjectClass *klass)
      47  {
      48    GObjectClass *object_class = G_OBJECT_CLASS (klass);
      49  
      50    object_class->constructor = my_singleton_object_constructor;
      51    object_class->finalize = my_singleton_object_finalize;
      52  }
      53  
      54  static void
      55  test_object_constructor_singleton (void)
      56  {
      57    MySingletonObject *one, *two, *three;
      58  
      59    one = g_object_new (my_singleton_object_get_type (), NULL);
      60    g_assert_cmpint (G_OBJECT (one)->ref_count, ==, 1);
      61  
      62    two = g_object_new (my_singleton_object_get_type (), NULL);
      63    g_assert (one == two);
      64    g_assert_cmpint (G_OBJECT (two)->ref_count, ==, 2);
      65  
      66    three = g_object_new (my_singleton_object_get_type (), NULL);
      67    g_assert (one == three);
      68    g_assert_cmpint (G_OBJECT (three)->ref_count, ==, 3);
      69  
      70    g_object_add_weak_pointer (G_OBJECT (one), (gpointer *)&one);
      71  
      72    g_object_unref (one);
      73    g_assert (one != NULL);
      74  
      75    g_object_unref (three);
      76    g_object_unref (two);
      77  
      78    g_assert (one == NULL);
      79  }
      80  
      81  /* ----------------------------------- */
      82  /* test_object_constructor_infanticide */
      83  
      84  typedef GObject MyInfanticideObject;
      85  typedef GObjectClass MyInfanticideObjectClass;
      86  
      87  GType my_infanticide_object_get_type (void);
      88  
      89  G_DEFINE_TYPE (MyInfanticideObject, my_infanticide_object, G_TYPE_OBJECT)
      90  
      91  static void
      92  my_infanticide_object_init (MyInfanticideObject *obj)
      93  {
      94  }
      95  
      96  static GObject *
      97  my_infanticide_object_constructor (GType                  type,
      98                                     guint                  n_construct_properties,
      99                                     GObjectConstructParam *construct_params)
     100  {
     101    GObject *object;
     102  
     103    object = G_OBJECT_CLASS (my_infanticide_object_parent_class)->
     104      constructor (type, n_construct_properties, construct_params);
     105  
     106    g_object_unref (object);
     107  
     108    return NULL;
     109  }
     110  
     111  static void
     112  my_infanticide_object_class_init (MyInfanticideObjectClass *klass)
     113  {
     114    GObjectClass *object_class = G_OBJECT_CLASS (klass);
     115  
     116    object_class->constructor = my_infanticide_object_constructor;
     117  }
     118  
     119  static void
     120  test_object_constructor_infanticide (void)
     121  {
     122    GObject *obj;
     123    int i;
     124  
     125  #ifndef G_ENABLE_DEBUG
     126    g_test_skip ("skip tests that rely on debug-only warnings");
     127    return;
     128  #endif
     129  
     130    g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=661576");
     131  
     132    for (i = 0; i < 1000; i++)
     133      {
     134        g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL,
     135                               "*finalized while still in-construction*");
     136        g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL,
     137                               "*Custom constructor*returned NULL*");
     138        obj = g_object_new (my_infanticide_object_get_type (), NULL);
     139        g_assert_null (obj);
     140        g_test_assert_expected_messages ();
     141      }
     142  }
     143  
     144  /* --------------------------------- */
     145  
     146  int
     147  main (int argc, char *argv[])
     148  {
     149    g_test_init (&argc, &argv, NULL);
     150  
     151    g_test_add_func ("/object/constructor/singleton", test_object_constructor_singleton);
     152    g_test_add_func ("/object/constructor/infanticide", test_object_constructor_infanticide);
     153  
     154    return g_test_run ();
     155  }