1 /* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 2000 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
22 #include "gstrfuncsprivate.h"
23 #include "gtypeplugin.h"
24 #include "gtypemodule.h"
29 * @short_description: Type loading modules
30 * @see_also: #GTypePlugin, #GModule
33 * #GTypeModule provides a simple implementation of the #GTypePlugin
34 * interface. The model of #GTypeModule is a dynamically loaded module
35 * which implements some number of types and interface implementations.
36 * When the module is loaded, it registers its types and interfaces
37 * using g_type_module_register_type() and g_type_module_add_interface().
38 * As long as any instances of these types and interface implementations
39 * are in use, the module is kept loaded. When the types and interfaces
40 * are gone, the module may be unloaded. If the types and interfaces
41 * become used again, the module will be reloaded. Note that the last
42 * unref cannot happen in module code, since that would lead to the
43 * caller's code being unloaded before g_object_unref() returns to it.
45 * Keeping track of whether the module should be loaded or not is done by
46 * using a use count - it starts at zero, and whenever it is greater than
47 * zero, the module is loaded. The use count is maintained internally by
48 * the type system, but also can be explicitly controlled by
49 * g_type_module_use() and g_type_module_unuse(). Typically, when loading
50 * a module for the first type, g_type_module_use() will be used to load
51 * it so that it can initialize its types. At some later point, when the
52 * module no longer needs to be loaded except for the type
53 * implementations it contains, g_type_module_unuse() is called.
55 * #GTypeModule does not actually provide any implementation of module
56 * loading and unloading. To create a particular module type you must
57 * derive from #GTypeModule and implement the load and unload functions
58 * in #GTypeModuleClass.
62 typedef struct _ModuleTypeInfo ModuleTypeInfo;
63 typedef struct _ModuleInterfaceInfo ModuleInterfaceInfo;
65 struct _ModuleTypeInfo
73 struct _ModuleInterfaceInfo
81 static void g_type_module_use_plugin (GTypePlugin *plugin);
82 static void g_type_module_complete_type_info (GTypePlugin *plugin,
85 GTypeValueTable *value_table);
86 static void g_type_module_complete_interface_info (GTypePlugin *plugin,
89 GInterfaceInfo *info);
91 static gpointer parent_class = NULL;
94 g_type_module_dispose (GObject *object)
96 GTypeModule *module = G_TYPE_MODULE (object);
98 if (module->type_infos || module->interface_infos)
100 g_warning (G_STRLOC ": unsolicitated invocation of g_object_run_dispose() on GTypeModule");
102 g_object_ref (object);
105 G_OBJECT_CLASS (parent_class)->dispose (object);
109 g_type_module_finalize (GObject *object)
111 GTypeModule *module = G_TYPE_MODULE (object);
113 g_free (module->name);
115 G_OBJECT_CLASS (parent_class)->finalize (object);
119 g_type_module_class_init (GTypeModuleClass *class)
121 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
123 parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (class));
125 gobject_class->dispose = g_type_module_dispose;
126 gobject_class->finalize = g_type_module_finalize;
130 g_type_module_iface_init (GTypePluginClass *iface)
132 iface->use_plugin = g_type_module_use_plugin;
133 iface->unuse_plugin = (void (*) (GTypePlugin *))g_type_module_unuse;
134 iface->complete_type_info = g_type_module_complete_type_info;
135 iface->complete_interface_info = g_type_module_complete_interface_info;
139 g_type_module_get_type (void)
141 static GType type_module_type = 0;
143 if (!type_module_type)
145 const GTypeInfo type_module_info = {
146 sizeof (GTypeModuleClass),
147 NULL, /* base_init */
148 NULL, /* base_finalize */
149 (GClassInitFunc) g_type_module_class_init,
150 NULL, /* class_finalize */
151 NULL, /* class_data */
152 sizeof (GTypeModule),
154 NULL, /* instance_init */
156 const GInterfaceInfo iface_info = {
157 (GInterfaceInitFunc) g_type_module_iface_init,
158 NULL, /* interface_finalize */
159 NULL, /* interface_data */
162 type_module_type = g_type_register_static (G_TYPE_OBJECT, g_intern_static_string ("GTypeModule"), &type_module_info, G_TYPE_FLAG_ABSTRACT);
164 g_type_add_interface_static (type_module_type, G_TYPE_TYPE_PLUGIN, &iface_info);
167 return type_module_type;
171 * g_type_module_set_name:
172 * @module: a #GTypeModule.
173 * @name: a human-readable name to use in error messages.
175 * Sets the name for a #GTypeModule
178 g_type_module_set_name (GTypeModule *module,
181 g_return_if_fail (G_IS_TYPE_MODULE (module));
183 g_free (module->name);
184 module->name = g_strdup (name);
187 static ModuleTypeInfo *
188 g_type_module_find_type_info (GTypeModule *module,
191 GSList *tmp_list = module->type_infos;
194 ModuleTypeInfo *type_info = tmp_list->data;
195 if (type_info->type == type)
198 tmp_list = tmp_list->next;
204 static ModuleInterfaceInfo *
205 g_type_module_find_interface_info (GTypeModule *module,
207 GType interface_type)
209 GSList *tmp_list = module->interface_infos;
212 ModuleInterfaceInfo *interface_info = tmp_list->data;
213 if (interface_info->instance_type == instance_type &&
214 interface_info->interface_type == interface_type)
215 return interface_info;
217 tmp_list = tmp_list->next;
225 * @module: a #GTypeModule
227 * Increases the use count of a #GTypeModule by one. If the
228 * use count was zero before, the plugin will be loaded.
229 * If loading the plugin fails, the use count is reset to
232 * Returns: %FALSE if the plugin needed to be loaded and
233 * loading the plugin failed.
236 g_type_module_use (GTypeModule *module)
238 g_return_val_if_fail (G_IS_TYPE_MODULE (module), FALSE);
241 if (module->use_count == 1)
245 if (!G_TYPE_MODULE_GET_CLASS (module)->load (module))
251 tmp_list = module->type_infos;
254 ModuleTypeInfo *type_info = tmp_list->data;
255 if (!type_info->loaded)
257 g_warning ("plugin '%s' failed to register type '%s'",
258 module->name ? module->name : "(unknown)",
259 g_type_name (type_info->type));
264 tmp_list = tmp_list->next;
272 * g_type_module_unuse:
273 * @module: a #GTypeModule
275 * Decreases the use count of a #GTypeModule by one. If the
276 * result is zero, the module will be unloaded. (However, the
277 * #GTypeModule will not be freed, and types associated with the
278 * #GTypeModule are not unregistered. Once a #GTypeModule is
279 * initialized, it must exist forever.)
282 g_type_module_unuse (GTypeModule *module)
284 g_return_if_fail (G_IS_TYPE_MODULE (module));
285 g_return_if_fail (module->use_count > 0);
289 if (module->use_count == 0)
293 G_TYPE_MODULE_GET_CLASS (module)->unload (module);
295 tmp_list = module->type_infos;
298 ModuleTypeInfo *type_info = tmp_list->data;
299 type_info->loaded = FALSE;
301 tmp_list = tmp_list->next;
307 g_type_module_use_plugin (GTypePlugin *plugin)
309 GTypeModule *module = G_TYPE_MODULE (plugin);
311 if (!g_type_module_use (module))
313 g_warning ("Fatal error - Could not reload previously loaded plugin '%s'",
314 module->name ? module->name : "(unknown)");
320 g_type_module_complete_type_info (GTypePlugin *plugin,
323 GTypeValueTable *value_table)
325 GTypeModule *module = G_TYPE_MODULE (plugin);
326 ModuleTypeInfo *module_type_info = g_type_module_find_type_info (module, g_type);
328 *info = module_type_info->info;
330 if (module_type_info->info.value_table)
331 *value_table = *module_type_info->info.value_table;
335 g_type_module_complete_interface_info (GTypePlugin *plugin,
337 GType interface_type,
338 GInterfaceInfo *info)
340 GTypeModule *module = G_TYPE_MODULE (plugin);
341 ModuleInterfaceInfo *module_interface_info = g_type_module_find_interface_info (module, instance_type, interface_type);
343 *info = module_interface_info->info;
347 * g_type_module_register_type:
348 * @module: (nullable): a #GTypeModule
349 * @parent_type: the type for the parent class
350 * @type_name: name for the type
351 * @type_info: type information structure
352 * @flags: flags field providing details about the type
354 * Looks up or registers a type that is implemented with a particular
355 * type plugin. If a type with name @type_name was previously registered,
356 * the #GType identifier for the type is returned, otherwise the type
357 * is newly registered, and the resulting #GType identifier returned.
359 * When reregistering a type (typically because a module is unloaded
360 * then reloaded, and reinitialized), @module and @parent_type must
361 * be the same as they were previously.
363 * As long as any instances of the type exist, the type plugin will
366 * Since 2.56 if @module is %NULL this will call g_type_register_static()
367 * instead. This can be used when making a static build of the module.
369 * Returns: the new or existing type ID
372 g_type_module_register_type (GTypeModule *module,
374 const gchar *type_name,
375 const GTypeInfo *type_info,
378 ModuleTypeInfo *module_type_info = NULL;
381 g_return_val_if_fail (type_name != NULL, 0);
382 g_return_val_if_fail (type_info != NULL, 0);
386 /* Cannot pass type_info directly to g_type_register_static() here because
387 * it has class_finalize != NULL and that's forbidden for static types */
388 return g_type_register_static_simple (parent_type,
390 type_info->class_size,
391 type_info->class_init,
392 type_info->instance_size,
393 type_info->instance_init,
397 type = g_type_from_name (type_name);
400 GTypePlugin *old_plugin = g_type_get_plugin (type);
402 if (old_plugin != G_TYPE_PLUGIN (module))
404 g_warning ("Two different plugins tried to register '%s'.", type_name);
411 module_type_info = g_type_module_find_type_info (module, type);
413 if (module_type_info->parent_type != parent_type)
415 const gchar *parent_type_name = g_type_name (parent_type);
417 g_warning ("Type '%s' recreated with different parent type."
418 "(was '%s', now '%s')", type_name,
419 g_type_name (module_type_info->parent_type),
420 parent_type_name ? parent_type_name : "(unknown)");
424 if (module_type_info->info.value_table)
425 g_free ((GTypeValueTable *) module_type_info->info.value_table);
429 module_type_info = g_new (ModuleTypeInfo, 1);
431 module_type_info->parent_type = parent_type;
432 module_type_info->type = g_type_register_dynamic (parent_type, type_name, G_TYPE_PLUGIN (module), flags);
434 module->type_infos = g_slist_prepend (module->type_infos, module_type_info);
437 module_type_info->loaded = TRUE;
438 module_type_info->info = *type_info;
439 if (type_info->value_table)
440 module_type_info->info.value_table = g_memdup2 (type_info->value_table,
441 sizeof (GTypeValueTable));
443 return module_type_info->type;
447 * g_type_module_add_interface:
448 * @module: (nullable): a #GTypeModule
449 * @instance_type: type to which to add the interface.
450 * @interface_type: interface type to add
451 * @interface_info: type information structure
453 * Registers an additional interface for a type, whose interface lives
454 * in the given type plugin. If the interface was already registered
455 * for the type in this plugin, nothing will be done.
457 * As long as any instances of the type exist, the type plugin will
460 * Since 2.56 if @module is %NULL this will call g_type_add_interface_static()
461 * instead. This can be used when making a static build of the module.
464 g_type_module_add_interface (GTypeModule *module,
466 GType interface_type,
467 const GInterfaceInfo *interface_info)
469 ModuleInterfaceInfo *module_interface_info = NULL;
471 g_return_if_fail (interface_info != NULL);
475 g_type_add_interface_static (instance_type, interface_type, interface_info);
479 if (g_type_is_a (instance_type, interface_type))
481 GTypePlugin *old_plugin = g_type_interface_get_plugin (instance_type,
486 g_warning ("Interface '%s' for '%s' was previously registered statically or for a parent type.",
487 g_type_name (interface_type), g_type_name (instance_type));
490 else if (old_plugin != G_TYPE_PLUGIN (module))
492 g_warning ("Two different plugins tried to register interface '%s' for '%s'.",
493 g_type_name (interface_type), g_type_name (instance_type));
497 module_interface_info = g_type_module_find_interface_info (module, instance_type, interface_type);
499 g_assert (module_interface_info);
503 module_interface_info = g_new (ModuleInterfaceInfo, 1);
505 module_interface_info->instance_type = instance_type;
506 module_interface_info->interface_type = interface_type;
508 g_type_add_interface_dynamic (instance_type, interface_type, G_TYPE_PLUGIN (module));
510 module->interface_infos = g_slist_prepend (module->interface_infos, module_interface_info);
513 module_interface_info->loaded = TRUE;
514 module_interface_info->info = *interface_info;
518 * g_type_module_register_enum:
519 * @module: (nullable): a #GTypeModule
520 * @name: name for the type
521 * @const_static_values: an array of #GEnumValue structs for the
522 * possible enumeration values. The array is
523 * terminated by a struct with all members being
526 * Looks up or registers an enumeration that is implemented with a particular
527 * type plugin. If a type with name @type_name was previously registered,
528 * the #GType identifier for the type is returned, otherwise the type
529 * is newly registered, and the resulting #GType identifier returned.
531 * As long as any instances of the type exist, the type plugin will
534 * Since 2.56 if @module is %NULL this will call g_type_register_static()
535 * instead. This can be used when making a static build of the module.
539 * Returns: the new or existing type ID
542 g_type_module_register_enum (GTypeModule *module,
544 const GEnumValue *const_static_values)
546 GTypeInfo enum_type_info = { 0, };
548 g_return_val_if_fail (module == NULL || G_IS_TYPE_MODULE (module), 0);
549 g_return_val_if_fail (name != NULL, 0);
550 g_return_val_if_fail (const_static_values != NULL, 0);
552 g_enum_complete_type_info (G_TYPE_ENUM,
553 &enum_type_info, const_static_values);
555 return g_type_module_register_type (G_TYPE_MODULE (module),
556 G_TYPE_ENUM, name, &enum_type_info, 0);
560 * g_type_module_register_flags:
561 * @module: (nullable): a #GTypeModule
562 * @name: name for the type
563 * @const_static_values: an array of #GFlagsValue structs for the
564 * possible flags values. The array is
565 * terminated by a struct with all members being
568 * Looks up or registers a flags type that is implemented with a particular
569 * type plugin. If a type with name @type_name was previously registered,
570 * the #GType identifier for the type is returned, otherwise the type
571 * is newly registered, and the resulting #GType identifier returned.
573 * As long as any instances of the type exist, the type plugin will
576 * Since 2.56 if @module is %NULL this will call g_type_register_static()
577 * instead. This can be used when making a static build of the module.
581 * Returns: the new or existing type ID
584 g_type_module_register_flags (GTypeModule *module,
586 const GFlagsValue *const_static_values)
588 GTypeInfo flags_type_info = { 0, };
590 g_return_val_if_fail (module == NULL || G_IS_TYPE_MODULE (module), 0);
591 g_return_val_if_fail (name != NULL, 0);
592 g_return_val_if_fail (const_static_values != NULL, 0);
594 g_flags_complete_type_info (G_TYPE_FLAGS,
595 &flags_type_info, const_static_values);
597 return g_type_module_register_type (G_TYPE_MODULE (module),
598 G_TYPE_FLAGS, name, &flags_type_info, 0);