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