(root)/
glib-2.79.0/
gobject/
gtypemodule.c
       1  /* GObject - GLib Type, Object, Parameter and Signal Library
       2   * Copyright (C) 2000 Red Hat, Inc.
       3   *
       4   * SPDX-License-Identifier: LGPL-2.1-or-later
       5   *
       6   * This library is free software; you can redistribute it and/or
       7   * modify it under the terms of the GNU Lesser General Public
       8   * License as published by the Free Software Foundation; either
       9   * version 2.1 of the License, or (at your option) any later version.
      10   *
      11   * This library 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.  See the GNU
      14   * Lesser General Public License for more details.
      15   *
      16   * You should have received a copy of the GNU Lesser General Public
      17   * License along with this library; if not, see <http://www.gnu.org/licenses/>.
      18   */
      19  
      20  #include "config.h"
      21  
      22  #include <stdlib.h>
      23  
      24  #include "gtypeplugin.h"
      25  #include "gtypemodule.h"
      26  
      27  
      28  /**
      29   * GTypeModule:
      30   * @name: the name of the module
      31   *
      32   * `GTypeModule` provides a simple implementation of the `GTypePlugin`
      33   * interface.
      34   *
      35   * The model of `GTypeModule` is a dynamically loaded module which
      36   * implements some number of types and interface implementations.
      37   *
      38   * When the module is loaded, it registers its types and interfaces
      39   * using [method@GObject.TypeModule.register_type] and
      40   * [method@GObject.TypeModule.add_interface].
      41   * As long as any instances of these types and interface implementations
      42   * are in use, the module is kept loaded. When the types and interfaces
      43   * are gone, the module may be unloaded. If the types and interfaces
      44   * become used again, the module will be reloaded. Note that the last
      45   * reference cannot be released from within the module code, since that
      46   * would lead to the caller's code being unloaded before `g_object_unref()`
      47   * returns to it.
      48   *
      49   * Keeping track of whether the module should be loaded or not is done by
      50   * using a use count - it starts at zero, and whenever it is greater than
      51   * zero, the module is loaded. The use count is maintained internally by
      52   * the type system, but also can be explicitly controlled by
      53   * [method@GObject.TypeModule.use] and [method@GObject.TypeModule.unuse].
      54   * Typically, when loading a module for the first type, `g_type_module_use()`
      55   * will be used to load it so that it can initialize its types. At some later
      56   * point, when the module no longer needs to be loaded except for the type
      57   * implementations it contains, `g_type_module_unuse()` is called.
      58   *
      59   * `GTypeModule` does not actually provide any implementation of module
      60   * loading and unloading. To create a particular module type you must
      61   * derive from `GTypeModule` and implement the load and unload functions
      62   * in `GTypeModuleClass`.
      63   */
      64  
      65  typedef struct _ModuleTypeInfo ModuleTypeInfo;
      66  typedef struct _ModuleInterfaceInfo ModuleInterfaceInfo;
      67  
      68  struct _ModuleTypeInfo 
      69  {
      70    gboolean  loaded;
      71    GType     type;
      72    GType     parent_type;
      73    GTypeInfo info;
      74  };
      75  
      76  struct _ModuleInterfaceInfo 
      77  {
      78    gboolean       loaded;
      79    GType          instance_type;
      80    GType          interface_type;
      81    GInterfaceInfo info;
      82  };
      83  
      84  static void g_type_module_use_plugin              (GTypePlugin     *plugin);
      85  static void g_type_module_complete_type_info      (GTypePlugin     *plugin,
      86  						   GType            g_type,
      87  						   GTypeInfo       *info,
      88  						   GTypeValueTable *value_table);
      89  static void g_type_module_complete_interface_info (GTypePlugin     *plugin,
      90  						   GType            instance_type,
      91  						   GType            interface_type,
      92  						   GInterfaceInfo  *info);
      93   
      94  static gpointer parent_class = NULL;
      95  
      96  static void
      97  g_type_module_dispose (GObject *object)
      98  {
      99    GTypeModule *module = G_TYPE_MODULE (object);
     100    
     101    if (module->type_infos || module->interface_infos)
     102      {
     103        g_critical (G_STRLOC ": unsolicitated invocation of g_object_run_dispose() on GTypeModule");
     104  
     105        g_object_ref (object);
     106      }
     107  
     108    G_OBJECT_CLASS (parent_class)->dispose (object);
     109  }
     110  
     111  static void
     112  g_type_module_finalize (GObject *object)
     113  {
     114    GTypeModule *module = G_TYPE_MODULE (object);
     115  
     116    g_free (module->name);
     117  
     118    /* in case a subclass does not chain-up to parent in dispose() */
     119    g_assert (module->type_infos == NULL);
     120    g_assert (module->interface_infos == NULL);
     121  
     122    G_OBJECT_CLASS (parent_class)->finalize (object);
     123  }
     124  
     125  static void
     126  g_type_module_class_init (GTypeModuleClass *class)
     127  {
     128    GObjectClass *gobject_class = G_OBJECT_CLASS (class);
     129  
     130    parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (class));
     131    
     132    gobject_class->dispose = g_type_module_dispose;
     133    gobject_class->finalize = g_type_module_finalize;
     134  }
     135  
     136  static void
     137  g_type_module_iface_init (GTypePluginClass *iface)
     138  {
     139    iface->use_plugin = g_type_module_use_plugin;
     140    iface->unuse_plugin = (void (*) (GTypePlugin *))g_type_module_unuse;
     141    iface->complete_type_info = g_type_module_complete_type_info;
     142    iface->complete_interface_info = g_type_module_complete_interface_info;
     143  }
     144  
     145  GType
     146  g_type_module_get_type (void)
     147  {
     148    static GType type_module_type = 0;
     149  
     150    if (!type_module_type)
     151      {
     152        const GTypeInfo type_module_info = {
     153          sizeof (GTypeModuleClass),
     154          NULL,           /* base_init */
     155          NULL,           /* base_finalize */
     156          (GClassInitFunc) g_type_module_class_init,
     157          NULL,           /* class_finalize */
     158          NULL,           /* class_data */
     159          sizeof (GTypeModule),
     160          0,              /* n_preallocs */
     161          NULL,           /* instance_init */
     162          NULL,           /* value_table */
     163        };
     164        const GInterfaceInfo iface_info = {
     165          (GInterfaceInitFunc) g_type_module_iface_init,
     166          NULL,               /* interface_finalize */
     167          NULL,               /* interface_data */
     168        };
     169  
     170        type_module_type = g_type_register_static (G_TYPE_OBJECT, g_intern_static_string ("GTypeModule"), &type_module_info, G_TYPE_FLAG_ABSTRACT);
     171  
     172        g_type_add_interface_static (type_module_type, G_TYPE_TYPE_PLUGIN, &iface_info);
     173      }
     174    
     175    return type_module_type;
     176  }
     177  
     178  /**
     179   * g_type_module_set_name:
     180   * @module: a #GTypeModule.
     181   * @name: a human-readable name to use in error messages.
     182   * 
     183   * Sets the name for a #GTypeModule 
     184   */
     185  void
     186  g_type_module_set_name (GTypeModule  *module,
     187  			const gchar  *name)
     188  {
     189    g_return_if_fail (G_IS_TYPE_MODULE (module));
     190  
     191    g_free (module->name);
     192    module->name = g_strdup (name);
     193  }
     194  
     195  static ModuleTypeInfo *
     196  g_type_module_find_type_info (GTypeModule *module,
     197  			      GType        type)
     198  {
     199    GSList *tmp_list = module->type_infos;
     200    while (tmp_list)
     201      {
     202        ModuleTypeInfo *type_info = tmp_list->data;
     203        if (type_info->type == type)
     204  	return type_info;
     205        
     206        tmp_list = tmp_list->next;
     207      }
     208  
     209    return NULL;
     210  }
     211  
     212  static ModuleInterfaceInfo *
     213  g_type_module_find_interface_info (GTypeModule *module,
     214  				   GType        instance_type,
     215  				   GType        interface_type)
     216  {
     217    GSList *tmp_list = module->interface_infos;
     218    while (tmp_list)
     219      {
     220        ModuleInterfaceInfo *interface_info = tmp_list->data;
     221        if (interface_info->instance_type == instance_type &&
     222  	  interface_info->interface_type == interface_type)
     223  	return interface_info;
     224        
     225        tmp_list = tmp_list->next;
     226      }
     227  
     228    return NULL;
     229  }
     230  
     231  /**
     232   * g_type_module_use:
     233   * @module: a #GTypeModule
     234   * 
     235   * Increases the use count of a #GTypeModule by one. If the
     236   * use count was zero before, the plugin will be loaded.
     237   * If loading the plugin fails, the use count is reset to 
     238   * its prior value. 
     239   * 
     240   * Returns: %FALSE if the plugin needed to be loaded and
     241   *  loading the plugin failed.
     242   */
     243  gboolean
     244  g_type_module_use (GTypeModule *module)
     245  {
     246    g_return_val_if_fail (G_IS_TYPE_MODULE (module), FALSE);
     247  
     248    module->use_count++;
     249    if (module->use_count == 1)
     250      {
     251        GSList *tmp_list;
     252        
     253        if (!G_TYPE_MODULE_GET_CLASS (module)->load (module))
     254  	{
     255  	  module->use_count--;
     256  	  return FALSE;
     257  	}
     258  
     259        tmp_list = module->type_infos;
     260        while (tmp_list)
     261  	{
     262  	  ModuleTypeInfo *type_info = tmp_list->data;
     263  	  if (!type_info->loaded)
     264  	    {
     265  	      g_critical ("plugin '%s' failed to register type '%s'",
     266  			  module->name ? module->name : "(unknown)",
     267  			  g_type_name (type_info->type));
     268  	      module->use_count--;
     269  	      return FALSE;
     270  	    }
     271  	  
     272  	  tmp_list = tmp_list->next;
     273  	}
     274      }
     275   
     276    return TRUE;
     277  }
     278  
     279  /**
     280   * g_type_module_unuse:
     281   * @module: a #GTypeModule
     282   *
     283   * Decreases the use count of a #GTypeModule by one. If the
     284   * result is zero, the module will be unloaded. (However, the
     285   * #GTypeModule will not be freed, and types associated with the
     286   * #GTypeModule are not unregistered. Once a #GTypeModule is
     287   * initialized, it must exist forever.)
     288   */
     289  void
     290  g_type_module_unuse (GTypeModule *module)
     291  {
     292    g_return_if_fail (G_IS_TYPE_MODULE (module));
     293    g_return_if_fail (module->use_count > 0);
     294  
     295    module->use_count--;
     296  
     297    if (module->use_count == 0)
     298      {
     299        GSList *tmp_list;
     300  
     301        G_TYPE_MODULE_GET_CLASS (module)->unload (module);
     302  
     303        tmp_list = module->type_infos;
     304        while (tmp_list)
     305  	{
     306  	  ModuleTypeInfo *type_info = tmp_list->data;
     307  	  type_info->loaded = FALSE;
     308  
     309  	  tmp_list = tmp_list->next;
     310  	}
     311      }
     312  }
     313  	
     314  static void
     315  g_type_module_use_plugin (GTypePlugin *plugin)
     316  {
     317    GTypeModule *module = G_TYPE_MODULE (plugin);
     318  
     319    if (!g_type_module_use (module))
     320      {
     321        g_error ("Fatal error - Could not reload previously loaded plugin '%s'",
     322  		module->name ? module->name : "(unknown)");
     323      }
     324  }
     325  
     326  static void
     327  g_type_module_complete_type_info (GTypePlugin     *plugin,
     328  				  GType            g_type,
     329  				  GTypeInfo       *info,
     330  				  GTypeValueTable *value_table)
     331  {
     332    GTypeModule *module = G_TYPE_MODULE (plugin);
     333    ModuleTypeInfo *module_type_info = g_type_module_find_type_info (module, g_type);
     334  
     335    *info = module_type_info->info;
     336    
     337    if (module_type_info->info.value_table)
     338      *value_table = *module_type_info->info.value_table;
     339  }
     340  
     341  static void 
     342  g_type_module_complete_interface_info (GTypePlugin    *plugin,
     343  				       GType           instance_type,
     344  				       GType           interface_type,
     345  				       GInterfaceInfo *info)
     346  {
     347    GTypeModule *module = G_TYPE_MODULE (plugin);
     348    ModuleInterfaceInfo *module_interface_info = g_type_module_find_interface_info (module, instance_type, interface_type);
     349  
     350    *info = module_interface_info->info;
     351  }
     352  
     353  /**
     354   * g_type_module_register_type:
     355   * @module: (nullable): a #GTypeModule
     356   * @parent_type: the type for the parent class
     357   * @type_name: name for the type
     358   * @type_info: type information structure
     359   * @flags: flags field providing details about the type
     360   *
     361   * Looks up or registers a type that is implemented with a particular
     362   * type plugin. If a type with name @type_name was previously registered,
     363   * the #GType identifier for the type is returned, otherwise the type
     364   * is newly registered, and the resulting #GType identifier returned.
     365   *
     366   * When reregistering a type (typically because a module is unloaded
     367   * then reloaded, and reinitialized), @module and @parent_type must
     368   * be the same as they were previously.
     369   *
     370   * As long as any instances of the type exist, the type plugin will
     371   * not be unloaded.
     372   *
     373   * Since 2.56 if @module is %NULL this will call g_type_register_static()
     374   * instead. This can be used when making a static build of the module.
     375   *
     376   * Returns: the new or existing type ID
     377   */
     378  GType
     379  g_type_module_register_type (GTypeModule     *module,
     380  			     GType            parent_type,
     381  			     const gchar     *type_name,
     382  			     const GTypeInfo *type_info,
     383  			     GTypeFlags       flags)
     384  {
     385    ModuleTypeInfo *module_type_info = NULL;
     386    GType type;
     387    
     388    g_return_val_if_fail (type_name != NULL, 0);
     389    g_return_val_if_fail (type_info != NULL, 0);
     390  
     391    if (module == NULL)
     392      {
     393        /* Cannot pass type_info directly to g_type_register_static() here because
     394         * it has class_finalize != NULL and that's forbidden for static types */
     395        return g_type_register_static_simple (parent_type,
     396                                              type_name,
     397                                              type_info->class_size,
     398                                              type_info->class_init,
     399                                              type_info->instance_size,
     400                                              type_info->instance_init,
     401                                              flags);
     402      }
     403  
     404    type = g_type_from_name (type_name);
     405    if (type)
     406      {
     407        GTypePlugin *old_plugin = g_type_get_plugin (type);
     408  
     409        if (old_plugin != G_TYPE_PLUGIN (module))
     410  	{
     411  	  g_critical ("Two different plugins tried to register '%s'.", type_name);
     412  	  return 0;
     413  	}
     414      }
     415  
     416    if (type)
     417      {
     418        module_type_info = g_type_module_find_type_info (module, type);
     419  
     420        if (module_type_info->parent_type != parent_type)
     421  	{
     422  	  const gchar *parent_type_name = g_type_name (parent_type);
     423  	  
     424  	  g_critical ("Type '%s' recreated with different parent type."
     425  		      "(was '%s', now '%s')", type_name,
     426  		      g_type_name (module_type_info->parent_type),
     427  		      parent_type_name ? parent_type_name : "(unknown)");
     428  	  return 0;
     429  	}
     430  
     431        if (module_type_info->info.value_table)
     432  	g_free ((GTypeValueTable *) module_type_info->info.value_table);
     433      }
     434    else
     435      {
     436        module_type_info = g_new (ModuleTypeInfo, 1);
     437        
     438        module_type_info->parent_type = parent_type;
     439        module_type_info->type = g_type_register_dynamic (parent_type, type_name, G_TYPE_PLUGIN (module), flags);
     440        
     441        module->type_infos = g_slist_prepend (module->type_infos, module_type_info);
     442      }
     443  
     444    module_type_info->loaded = TRUE;
     445    module_type_info->info = *type_info;
     446    if (type_info->value_table)
     447      module_type_info->info.value_table = g_memdup2 (type_info->value_table,
     448  						   sizeof (GTypeValueTable));
     449  
     450    return module_type_info->type;
     451  }
     452  
     453  /**
     454   * g_type_module_add_interface:
     455   * @module: (nullable): a #GTypeModule
     456   * @instance_type: type to which to add the interface.
     457   * @interface_type: interface type to add
     458   * @interface_info: type information structure
     459   *
     460   * Registers an additional interface for a type, whose interface lives
     461   * in the given type plugin. If the interface was already registered
     462   * for the type in this plugin, nothing will be done.
     463   *
     464   * As long as any instances of the type exist, the type plugin will
     465   * not be unloaded.
     466   *
     467   * Since 2.56 if @module is %NULL this will call g_type_add_interface_static()
     468   * instead. This can be used when making a static build of the module.
     469   */
     470  void
     471  g_type_module_add_interface (GTypeModule          *module,
     472  			     GType                 instance_type,
     473  			     GType                 interface_type,
     474  			     const GInterfaceInfo *interface_info)
     475  {
     476    ModuleInterfaceInfo *module_interface_info = NULL;
     477  
     478    g_return_if_fail (interface_info != NULL);
     479  
     480    if (module == NULL)
     481      {
     482        g_type_add_interface_static (instance_type, interface_type, interface_info);
     483        return;
     484      }
     485  
     486    if (g_type_is_a (instance_type, interface_type))
     487      {
     488        GTypePlugin *old_plugin = g_type_interface_get_plugin (instance_type,
     489  							     interface_type);
     490  
     491        if (!old_plugin)
     492  	{
     493  	  g_critical ("Interface '%s' for '%s' was previously registered statically or for a parent type.",
     494  		      g_type_name (interface_type), g_type_name (instance_type));
     495  	  return;
     496  	}
     497        else if (old_plugin != G_TYPE_PLUGIN (module))
     498  	{
     499  	  g_critical ("Two different plugins tried to register interface '%s' for '%s'.",
     500  		      g_type_name (interface_type), g_type_name (instance_type));
     501  	  return;
     502  	}
     503        
     504        module_interface_info = g_type_module_find_interface_info (module, instance_type, interface_type);
     505  
     506        g_assert (module_interface_info);
     507      }
     508    else
     509      {
     510        module_interface_info = g_new (ModuleInterfaceInfo, 1);
     511        
     512        module_interface_info->instance_type = instance_type;
     513        module_interface_info->interface_type = interface_type;
     514        
     515        g_type_add_interface_dynamic (instance_type, interface_type, G_TYPE_PLUGIN (module));
     516        
     517        module->interface_infos = g_slist_prepend (module->interface_infos, module_interface_info);
     518      }
     519    
     520    module_interface_info->loaded = TRUE;
     521    module_interface_info->info = *interface_info;
     522  }
     523  
     524  /**
     525   * g_type_module_register_enum:
     526   * @module: (nullable): a #GTypeModule
     527   * @name: name for the type
     528   * @const_static_values: an array of #GEnumValue structs for the
     529   *                       possible enumeration values. The array is
     530   *                       terminated by a struct with all members being
     531   *                       0.
     532   *
     533   * Looks up or registers an enumeration that is implemented with a particular
     534   * type plugin. If a type with name @type_name was previously registered,
     535   * the #GType identifier for the type is returned, otherwise the type
     536   * is newly registered, and the resulting #GType identifier returned.
     537   *
     538   * As long as any instances of the type exist, the type plugin will
     539   * not be unloaded.
     540   *
     541   * Since 2.56 if @module is %NULL this will call g_type_register_static()
     542   * instead. This can be used when making a static build of the module.
     543   *
     544   * Since: 2.6
     545   *
     546   * Returns: the new or existing type ID
     547   */
     548  GType
     549  g_type_module_register_enum (GTypeModule      *module,
     550                               const gchar      *name,
     551                               const GEnumValue *const_static_values)
     552  {
     553    GTypeInfo enum_type_info = { 0, };
     554  
     555    g_return_val_if_fail (module == NULL || G_IS_TYPE_MODULE (module), 0);
     556    g_return_val_if_fail (name != NULL, 0);
     557    g_return_val_if_fail (const_static_values != NULL, 0);
     558  
     559    g_enum_complete_type_info (G_TYPE_ENUM,
     560                               &enum_type_info, const_static_values);
     561  
     562    return g_type_module_register_type (G_TYPE_MODULE (module),
     563                                        G_TYPE_ENUM, name, &enum_type_info, 0);
     564  }
     565  
     566  /**
     567   * g_type_module_register_flags:
     568   * @module: (nullable): a #GTypeModule
     569   * @name: name for the type
     570   * @const_static_values: an array of #GFlagsValue structs for the
     571   *                       possible flags values. The array is
     572   *                       terminated by a struct with all members being
     573   *                       0.
     574   *
     575   * Looks up or registers a flags type that is implemented with a particular
     576   * type plugin. If a type with name @type_name was previously registered,
     577   * the #GType identifier for the type is returned, otherwise the type
     578   * is newly registered, and the resulting #GType identifier returned.
     579   *
     580   * As long as any instances of the type exist, the type plugin will
     581   * not be unloaded.
     582   *
     583   * Since 2.56 if @module is %NULL this will call g_type_register_static()
     584   * instead. This can be used when making a static build of the module.
     585   *
     586   * Since: 2.6
     587   *
     588   * Returns: the new or existing type ID
     589   */
     590  GType
     591  g_type_module_register_flags (GTypeModule      *module,
     592                               const gchar       *name,
     593                               const GFlagsValue *const_static_values)
     594  {
     595    GTypeInfo flags_type_info = { 0, };
     596  
     597    g_return_val_if_fail (module == NULL || G_IS_TYPE_MODULE (module), 0);
     598    g_return_val_if_fail (name != NULL, 0);
     599    g_return_val_if_fail (const_static_values != NULL, 0);
     600  
     601    g_flags_complete_type_info (G_TYPE_FLAGS,
     602                               &flags_type_info, const_static_values);
     603  
     604    return g_type_module_register_type (G_TYPE_MODULE (module),
     605                                        G_TYPE_FLAGS, name, &flags_type_info, 0);
     606  }