LCOV - code coverage report
Current view: top level - gobject/tests - dynamictests.c (source / functions) Coverage Total Hit
Test: unnamed Lines: 84.0 % 119 100
Test Date: 2024-11-26 05:23:01 Functions: 89.3 % 28 25
Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* GLib testing framework examples and tests
       2                 :             :  * Copyright (C) 2008 Imendio AB
       3                 :             :  * Authors: Tim Janik
       4                 :             :  *
       5                 :             :  * SPDX-License-Identifier: LicenseRef-old-glib-tests
       6                 :             :  *
       7                 :             :  * This work is provided "as is"; redistribution and modification
       8                 :             :  * in whole or in part, in any medium, physical or electronic is
       9                 :             :  * permitted without restriction.
      10                 :             :  *
      11                 :             :  * This work is distributed in the hope that it will be useful,
      12                 :             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13                 :             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      14                 :             :  *
      15                 :             :  * In no event shall the authors or contributors be liable for any
      16                 :             :  * direct, indirect, incidental, special, exemplary, or consequential
      17                 :             :  * damages (including, but not limited to, procurement of substitute
      18                 :             :  * goods or services; loss of use, data, or profits; or business
      19                 :             :  * interruption) however caused and on any theory of liability, whether
      20                 :             :  * in contract, strict liability, or tort (including negligence or
      21                 :             :  * otherwise) arising in any way out of the use of this software, even
      22                 :             :  * if advised of the possibility of such damage.
      23                 :             :  */
      24                 :             : #include <glib.h>
      25                 :             : #include <glib-object.h>
      26                 :             : 
      27                 :             : /* This test tests the macros for defining dynamic types.
      28                 :             :  */
      29                 :             : 
      30                 :             : static GMutex sync_mutex;
      31                 :             : static gboolean loaded = FALSE;
      32                 :             : 
      33                 :             : /* MODULE */
      34                 :             : typedef struct _TestModule      TestModule;
      35                 :             : typedef struct _TestModuleClass TestModuleClass;
      36                 :             : 
      37                 :             : #define TEST_TYPE_MODULE              (test_module_get_type ())
      38                 :             : #define TEST_MODULE(module)           (G_TYPE_CHECK_INSTANCE_CAST ((module), TEST_TYPE_MODULE, TestModule))
      39                 :             : #define TEST_MODULE_CLASS(class)      (G_TYPE_CHECK_CLASS_CAST ((class), TEST_TYPE_MODULE, TestModuleClass))
      40                 :             : #define TEST_IS_MODULE(module)        (G_TYPE_CHECK_INSTANCE_TYPE ((module), TEST_TYPE_MODULE))
      41                 :             : #define TEST_IS_MODULE_CLASS(class)   (G_TYPE_CHECK_CLASS_TYPE ((class), TEST_TYPE_MODULE))
      42                 :             : #define TEST_MODULE_GET_CLASS(module) (G_TYPE_INSTANCE_GET_CLASS ((module), TEST_TYPE_MODULE, TestModuleClass))
      43                 :             : typedef void (*TestModuleRegisterFunc) (GTypeModule *module);
      44                 :             : 
      45                 :             : struct _TestModule
      46                 :             : {
      47                 :             :   GTypeModule parent_instance;
      48                 :             : 
      49                 :             :   TestModuleRegisterFunc register_func;
      50                 :             : };
      51                 :             : 
      52                 :             : struct _TestModuleClass
      53                 :             : {
      54                 :             :   GTypeModuleClass parent_class;
      55                 :             : };
      56                 :             : 
      57                 :             : static GType test_module_get_type (void);
      58                 :             : 
      59                 :             : static gboolean
      60                 :           4 : test_module_load (GTypeModule *module)
      61                 :             : {
      62                 :           4 :   TestModule *test_module = TEST_MODULE (module);
      63                 :             : 
      64                 :           4 :   test_module->register_func (module);
      65                 :             : 
      66                 :           4 :   return TRUE;
      67                 :             : }
      68                 :             : 
      69                 :             : static void
      70                 :           2 : test_module_unload (GTypeModule *module)
      71                 :             : {
      72                 :           2 : }
      73                 :             : 
      74                 :             : static void
      75                 :           1 : test_module_class_init (TestModuleClass *class)
      76                 :             : {
      77                 :           1 :   GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
      78                 :             : 
      79                 :           1 :   module_class->load = test_module_load;
      80                 :           1 :   module_class->unload = test_module_unload;
      81                 :           1 : }
      82                 :             : 
      83                 :           6 : static GType test_module_get_type (void)
      84                 :             : {
      85                 :             :   static GType object_type = 0;
      86                 :             : 
      87                 :           6 :   if (!object_type) {
      88                 :             :     static const GTypeInfo object_info =
      89                 :             :       {
      90                 :             :         sizeof (TestModuleClass),
      91                 :             :         (GBaseInitFunc) NULL,
      92                 :             :         (GBaseFinalizeFunc) NULL,
      93                 :             :         (GClassInitFunc) test_module_class_init,
      94                 :             :         (GClassFinalizeFunc) NULL,
      95                 :             :         NULL,
      96                 :             :         sizeof (TestModule),
      97                 :             :         0,
      98                 :             :         (GInstanceInitFunc)NULL,
      99                 :             :         NULL,
     100                 :             :       };
     101                 :           1 :     object_type = g_type_register_static (G_TYPE_TYPE_MODULE, "TestModule", &object_info, 0);
     102                 :             :   }
     103                 :           6 :   return object_type;
     104                 :             : }
     105                 :             : 
     106                 :             : 
     107                 :             : static GTypeModule *
     108                 :           2 : test_module_new (TestModuleRegisterFunc register_func)
     109                 :             : {
     110                 :           2 :   TestModule *test_module = g_object_new (TEST_TYPE_MODULE, NULL);
     111                 :           2 :   GTypeModule *module = G_TYPE_MODULE (test_module);
     112                 :             : 
     113                 :           2 :   test_module->register_func = register_func;
     114                 :             : 
     115                 :             :   /* Register the types initially */
     116                 :           2 :   g_type_module_use (module);
     117                 :           2 :   g_type_module_unuse (module);
     118                 :             : 
     119                 :           2 :   return G_TYPE_MODULE (module);
     120                 :             : }
     121                 :             : 
     122                 :             : 
     123                 :             : 
     124                 :             : #define DYNAMIC_OBJECT_TYPE (dynamic_object_get_type ())
     125                 :             : 
     126                 :             : typedef GObject DynamicObject;
     127                 :             : typedef struct _DynamicObjectClass DynamicObjectClass;
     128                 :             : 
     129                 :             : struct _DynamicObjectClass
     130                 :             : {
     131                 :             :   GObjectClass parent_class;
     132                 :             :   guint val;
     133                 :             : };
     134                 :             : 
     135                 :             : static GType dynamic_object_get_type (void);
     136                 :         104 : G_DEFINE_DYNAMIC_TYPE(DynamicObject, dynamic_object, G_TYPE_OBJECT)
     137                 :             : 
     138                 :             : static void
     139                 :           1 : dynamic_object_class_init (DynamicObjectClass *class)
     140                 :             : {
     141                 :           1 :   class->val = 42;
     142                 :           1 :   g_assert (loaded == FALSE);
     143                 :           1 :   loaded = TRUE;
     144                 :           1 : }
     145                 :             : 
     146                 :             : static void
     147                 :           0 : dynamic_object_class_finalize (DynamicObjectClass *class)
     148                 :             : {
     149                 :           0 :   g_assert (loaded == TRUE);
     150                 :           0 :   loaded = FALSE;
     151                 :           0 : }
     152                 :             : 
     153                 :             : static void
     154                 :           0 : dynamic_object_init (DynamicObject *dynamic_object)
     155                 :             : {
     156                 :           0 : }
     157                 :             : 
     158                 :             : 
     159                 :             : static void
     160                 :           2 : module_register (GTypeModule *module)
     161                 :             : {
     162                 :           2 :   dynamic_object_register_type (module);
     163                 :           2 : }
     164                 :             : 
     165                 :             : #define N_THREADS 100
     166                 :             : #define N_REFS 10000
     167                 :             : 
     168                 :             : static gpointer
     169                 :         100 : ref_unref_thread (gpointer data)
     170                 :             : {
     171                 :             :   gint i;
     172                 :             :   /* first, synchronize with other threads,
     173                 :             :    */
     174                 :         100 :   if (g_test_verbose())
     175                 :           0 :     g_printerr ("WAITING!\n");
     176                 :         100 :   g_mutex_lock (&sync_mutex);
     177                 :         100 :   g_mutex_unlock (&sync_mutex);
     178                 :         100 :   if (g_test_verbose ())
     179                 :           0 :     g_printerr ("STARTING\n");
     180                 :             : 
     181                 :             :   /* ref/unref the klass 10000000 times */
     182                 :     1000100 :   for (i = N_REFS; i; i--) {
     183                 :     1000000 :     if (g_test_verbose ())
     184                 :           0 :       if (i % 10)
     185                 :           0 :         g_printerr ("%d\n", i);
     186                 :     1000000 :     g_type_class_unref (g_type_class_ref ((GType) data));
     187                 :             :   }
     188                 :             : 
     189                 :         100 :   if (g_test_verbose())
     190                 :           0 :     g_printerr ("DONE !\n");
     191                 :             : 
     192                 :         100 :   return NULL;
     193                 :             : }
     194                 :             : 
     195                 :             : static void
     196                 :           1 : test_multithreaded_dynamic_type_init (void)
     197                 :             : {
     198                 :             :   GTypeModule *module;
     199                 :             :   DynamicObjectClass *class;
     200                 :             :   /* Create N_THREADS threads that are going to just ref/unref a class */
     201                 :             :   GThread *threads[N_THREADS];
     202                 :             :   guint i;
     203                 :             : 
     204                 :           1 :   module = test_module_new (module_register);
     205                 :           1 :   g_assert (module != NULL);
     206                 :             : 
     207                 :             :   /* Not loaded until we call ref for the first time */
     208                 :           1 :   class = g_type_class_peek (DYNAMIC_OBJECT_TYPE);
     209                 :           1 :   g_assert (class == NULL);
     210                 :           1 :   g_assert (!loaded);
     211                 :             : 
     212                 :             :   /* pause newly created threads */
     213                 :           1 :   g_mutex_lock (&sync_mutex);
     214                 :             : 
     215                 :             :   /* create threads */
     216                 :         101 :   for (i = 0; i < N_THREADS; i++) {
     217                 :         100 :     threads[i] = g_thread_new ("test", ref_unref_thread, (gpointer) DYNAMIC_OBJECT_TYPE);
     218                 :             :   }
     219                 :             : 
     220                 :             :   /* execute threads */
     221                 :           1 :   g_mutex_unlock (&sync_mutex);
     222                 :             : 
     223                 :         101 :   for (i = 0; i < N_THREADS; i++) {
     224                 :         100 :     g_thread_join (threads[i]);
     225                 :             :   }
     226                 :           1 : }
     227                 :             : 
     228                 :             : enum
     229                 :             : {
     230                 :             :   PROP_0,
     231                 :             :   PROP_FOO
     232                 :             : };
     233                 :             : 
     234                 :             : typedef struct _DynObj DynObj;
     235                 :             : typedef struct _DynObjClass DynObjClass;
     236                 :             : typedef struct _DynIfaceInterface DynIfaceInterface;
     237                 :             : 
     238                 :             : struct _DynObj
     239                 :             : {
     240                 :             :   GObject obj;
     241                 :             : 
     242                 :             :   gint foo;
     243                 :             : };
     244                 :             : 
     245                 :             : struct _DynObjClass
     246                 :             : {
     247                 :             :   GObjectClass class;
     248                 :             : };
     249                 :             : 
     250                 :             : struct _DynIfaceInterface
     251                 :             : {
     252                 :             :   GTypeInterface iface;
     253                 :             : };
     254                 :             : 
     255                 :             : static void dyn_obj_iface_init (DynIfaceInterface *iface);
     256                 :             : 
     257                 :             : static GType dyn_iface_get_type (void);
     258                 :           2 : G_DEFINE_INTERFACE (DynIface, dyn_iface, G_TYPE_OBJECT)
     259                 :             : 
     260                 :             : static GType dyn_obj_get_type (void);
     261                 :           4 : G_DEFINE_DYNAMIC_TYPE_EXTENDED(DynObj, dyn_obj, G_TYPE_OBJECT, 0,
     262                 :             :                       G_IMPLEMENT_INTERFACE_DYNAMIC(dyn_iface_get_type (), dyn_obj_iface_init))
     263                 :             : 
     264                 :             : 
     265                 :             : static void
     266                 :           1 : dyn_iface_default_init (DynIfaceInterface *iface)
     267                 :             : {
     268                 :           1 :   g_object_interface_install_property (iface,
     269                 :             :     g_param_spec_int ("foo", NULL, NULL, 0, 100, 0, G_PARAM_READWRITE));
     270                 :           1 : }
     271                 :             : 
     272                 :             : static void
     273                 :           1 : dyn_obj_iface_init (DynIfaceInterface *iface)
     274                 :             : {
     275                 :           1 : }
     276                 :             : 
     277                 :             : static void
     278                 :           1 : dyn_obj_init (DynObj *obj)
     279                 :             : {
     280                 :           1 :   obj->foo = 0;
     281                 :           1 : }
     282                 :             : 
     283                 :             : static void
     284                 :           1 : set_prop (GObject      *object,
     285                 :             :           guint         prop_id,
     286                 :             :           const GValue *value,
     287                 :             :           GParamSpec   *pspec)
     288                 :             : {
     289                 :           1 :   DynObj *obj = (DynObj *)object;
     290                 :             : 
     291                 :           1 :   switch (prop_id)
     292                 :             :     {
     293                 :           1 :     case PROP_FOO:
     294                 :           1 :       obj->foo = g_value_get_int (value);
     295                 :           1 :       break;
     296                 :           0 :     default:
     297                 :           0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     298                 :           0 :       break;
     299                 :             :     }
     300                 :           1 : }
     301                 :             : 
     302                 :             : static void
     303                 :           1 : get_prop (GObject    *object,
     304                 :             :           guint       prop_id,
     305                 :             :           GValue     *value,
     306                 :             :           GParamSpec *pspec)
     307                 :             : {
     308                 :           1 :   DynObj *obj = (DynObj *)object;
     309                 :             : 
     310                 :           1 :   switch (prop_id)
     311                 :             :     {
     312                 :           1 :     case PROP_FOO:
     313                 :           1 :       g_value_set_int (value, obj->foo);
     314                 :           1 :       break;
     315                 :           0 :     default:
     316                 :           0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     317                 :           0 :       break;
     318                 :             :     }
     319                 :           1 : }
     320                 :             : 
     321                 :             : static void
     322                 :           1 : dyn_obj_class_init (DynObjClass *class)
     323                 :             : {
     324                 :           1 :   GObjectClass *object_class = G_OBJECT_CLASS (class);
     325                 :             : 
     326                 :           1 :   object_class->set_property = set_prop;
     327                 :           1 :   object_class->get_property = get_prop;
     328                 :             : 
     329                 :           1 :   g_object_class_override_property (object_class, PROP_FOO, "foo");
     330                 :           1 : }
     331                 :             : 
     332                 :             : static void
     333                 :           0 : dyn_obj_class_finalize (DynObjClass *class)
     334                 :             : {
     335                 :           0 : }
     336                 :             : 
     337                 :             : static void
     338                 :           2 : mod_register (GTypeModule *module)
     339                 :             : {
     340                 :           2 :   dyn_obj_register_type (module);
     341                 :           2 : }
     342                 :             : 
     343                 :             : static void
     344                 :           1 : test_dynamic_interface_properties (void)
     345                 :             : {
     346                 :             :   GTypeModule *module;
     347                 :             :   DynObj *obj;
     348                 :             :   gint val;
     349                 :             : 
     350                 :           1 :   module = test_module_new (mod_register);
     351                 :           1 :   g_assert (module != NULL);
     352                 :             : 
     353                 :           1 :   obj = g_object_new (dyn_obj_get_type (), "foo", 1, NULL);
     354                 :           1 :   g_object_get (obj, "foo", &val, NULL);
     355                 :           1 :   g_assert_cmpint (val, ==, 1);
     356                 :             : 
     357                 :           1 :   g_object_unref (obj);
     358                 :           1 : }
     359                 :             : 
     360                 :             : int
     361                 :           1 : main (int   argc,
     362                 :             :       char *argv[])
     363                 :             : {
     364                 :           1 :   g_test_init (&argc, &argv, NULL);
     365                 :             : 
     366                 :           1 :   g_test_add_func ("/GObject/threaded-dynamic-ref-unref-init", test_multithreaded_dynamic_type_init);
     367                 :           1 :   g_test_add_func ("/GObject/dynamic-interface-properties", test_dynamic_interface_properties);
     368                 :             : 
     369                 :           1 :   return g_test_run();
     370                 :             : }
        

Generated by: LCOV version 2.0-1