• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc.
3  *
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.
8  *
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.
13  *
14  * You should have received a copy of the GNU Lesser General
15  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 /*
19  * MT safe
20  */
21 
22 #include "config.h"
23 
24 #include "../glib/gvalgrind.h"
25 #include <string.h>
26 
27 #include "gtype.h"
28 #include "gtype-private.h"
29 #include "gtypeplugin.h"
30 #include "gvaluecollector.h"
31 #include "gatomicarray.h"
32 #include "gobject_trace.h"
33 
34 #include "glib-private.h"
35 #include "gconstructor.h"
36 
37 #ifdef G_OS_WIN32
38 #include <windows.h>
39 #endif
40 
41 #ifdef	G_ENABLE_DEBUG
42 #define	IF_DEBUG(debug_type)	if (_g_type_debug_flags & G_TYPE_DEBUG_ ## debug_type)
43 #endif
44 
45 /**
46  * SECTION:gtype
47  * @short_description: The GLib Runtime type identification and
48  *     management system
49  * @title:Type Information
50  *
51  * The GType API is the foundation of the GObject system.  It provides the
52  * facilities for registering and managing all fundamental data types,
53  * user-defined object and interface types.
54  *
55  * For type creation and registration purposes, all types fall into one of
56  * two categories: static or dynamic.  Static types are never loaded or
57  * unloaded at run-time as dynamic types may be.  Static types are created
58  * with g_type_register_static() that gets type specific information passed
59  * in via a #GTypeInfo structure.
60  *
61  * Dynamic types are created with g_type_register_dynamic() which takes a
62  * #GTypePlugin structure instead. The remaining type information (the
63  * #GTypeInfo structure) is retrieved during runtime through #GTypePlugin
64  * and the g_type_plugin_*() API.
65  *
66  * These registration functions are usually called only once from a
67  * function whose only purpose is to return the type identifier for a
68  * specific class.  Once the type (or class or interface) is registered,
69  * it may be instantiated, inherited, or implemented depending on exactly
70  * what sort of type it is.
71  *
72  * There is also a third registration function for registering fundamental
73  * types called g_type_register_fundamental() which requires both a #GTypeInfo
74  * structure and a #GTypeFundamentalInfo structure but it is seldom used
75  * since most fundamental types are predefined rather than user-defined.
76  *
77  * Type instance and class structs are limited to a total of 64 KiB,
78  * including all parent types. Similarly, type instances' private data
79  * (as created by G_ADD_PRIVATE()) are limited to a total of
80  * 64 KiB. If a type instance needs a large static buffer, allocate it
81  * separately (typically by using #GArray or #GPtrArray) and put a pointer
82  * to the buffer in the structure.
83  *
84  * As mentioned in the [GType conventions][gtype-conventions], type names must
85  * be at least three characters long. There is no upper length limit. The first
86  * character must be a letter (a–z or A–Z) or an underscore (‘_’). Subsequent
87  * characters can be letters, numbers or any of ‘-_+’.
88  */
89 
90 
91 /* NOTE: some functions (some internal variants and exported ones)
92  * invalidate data portions of the TypeNodes. if external functions/callbacks
93  * are called, pointers to memory maintained by TypeNodes have to be looked up
94  * again. this affects most of the struct TypeNode fields, e.g. ->children or
95  * CLASSED_NODE_IFACES_ENTRIES() respectively IFACE_NODE_PREREQUISITES() (but
96  * not ->supers[]), as all those memory portions can get realloc()ed during
97  * callback invocation.
98  *
99  * LOCKING:
100  * lock handling issues when calling static functions are indicated by
101  * uppercase letter postfixes, all static functions have to have
102  * one of the below postfixes:
103  * - _I:	[Indifferent about locking]
104  *   function doesn't care about locks at all
105  * - _U:	[Unlocked invocation]
106  *   no read or write lock has to be held across function invocation
107  *   (locks may be acquired and released during invocation though)
108  * - _L:	[Locked invocation]
109  *   a write lock or more than 0 read locks have to be held across
110  *   function invocation
111  * - _W:	[Write-locked invocation]
112  *   a write lock has to be held across function invocation
113  * - _Wm:	[Write-locked invocation, mutatable]
114  *   like _W, but the write lock might be released and reacquired
115  *   during invocation, watch your pointers
116  * - _WmREC:    [Write-locked invocation, mutatable, recursive]
117  *   like _Wm, but also acquires recursive mutex class_init_rec_mutex
118  */
119 
120 #ifdef LOCK_DEBUG
121 #define G_READ_LOCK(rw_lock)    do { g_printerr (G_STRLOC ": readL++\n"); g_rw_lock_reader_lock (rw_lock); } while (0)
122 #define G_READ_UNLOCK(rw_lock)  do { g_printerr (G_STRLOC ": readL--\n"); g_rw_lock_reader_unlock (rw_lock); } while (0)
123 #define G_WRITE_LOCK(rw_lock)   do { g_printerr (G_STRLOC ": writeL++\n"); g_rw_lock_writer_lock (rw_lock); } while (0)
124 #define G_WRITE_UNLOCK(rw_lock) do { g_printerr (G_STRLOC ": writeL--\n"); g_rw_lock_writer_unlock (rw_lock); } while (0)
125 #else
126 #define G_READ_LOCK(rw_lock)    g_rw_lock_reader_lock (rw_lock)
127 #define G_READ_UNLOCK(rw_lock)  g_rw_lock_reader_unlock (rw_lock)
128 #define G_WRITE_LOCK(rw_lock)   g_rw_lock_writer_lock (rw_lock)
129 #define G_WRITE_UNLOCK(rw_lock) g_rw_lock_writer_unlock (rw_lock)
130 #endif
131 #define	INVALID_RECURSION(func, arg, type_name) G_STMT_START{ \
132     static const gchar _action[] = " invalidly modified type ";  \
133     gpointer _arg = (gpointer) (arg); const gchar *_tname = (type_name), *_fname = (func); \
134     if (_arg) \
135       g_error ("%s(%p)%s'%s'", _fname, _arg, _action, _tname); \
136     else \
137       g_error ("%s()%s'%s'", _fname, _action, _tname); \
138 }G_STMT_END
139 #define g_assert_type_system_initialized() \
140   g_assert (static_quark_type_flags)
141 
142 #define TYPE_FUNDAMENTAL_FLAG_MASK (G_TYPE_FLAG_CLASSED | \
143 				    G_TYPE_FLAG_INSTANTIATABLE | \
144 				    G_TYPE_FLAG_DERIVABLE | \
145 				    G_TYPE_FLAG_DEEP_DERIVABLE)
146 #define	TYPE_FLAG_MASK		   (G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT)
147 #define	SIZEOF_FUNDAMENTAL_INFO	   ((gssize) MAX (MAX (sizeof (GTypeFundamentalInfo), \
148 						       sizeof (gpointer)), \
149                                                   sizeof (glong)))
150 
151 /* The 2*sizeof(size_t) alignment here is borrowed from
152  * GNU libc, so it should be good most everywhere.
153  * It is more conservative than is needed on some 64-bit
154  * platforms, but ia64 does require a 16-byte alignment.
155  * The SIMD extensions for x86 and ppc32 would want a
156  * larger alignment than this, but we don't need to
157  * do better than malloc.
158  */
159 #define STRUCT_ALIGNMENT (2 * sizeof (gsize))
160 #define ALIGN_STRUCT(offset) \
161       ((offset + (STRUCT_ALIGNMENT - 1)) & -STRUCT_ALIGNMENT)
162 
163 
164 /* --- typedefs --- */
165 typedef struct _TypeNode        TypeNode;
166 typedef struct _CommonData      CommonData;
167 typedef struct _BoxedData       BoxedData;
168 typedef struct _IFaceData       IFaceData;
169 typedef struct _ClassData       ClassData;
170 typedef struct _InstanceData    InstanceData;
171 typedef union  _TypeData        TypeData;
172 typedef struct _IFaceEntries    IFaceEntries;
173 typedef struct _IFaceEntry      IFaceEntry;
174 typedef struct _IFaceHolder	IFaceHolder;
175 
176 
177 /* --- prototypes --- */
178 static inline GTypeFundamentalInfo*	type_node_fundamental_info_I	(TypeNode		*node);
179 static	      void			type_add_flags_W		(TypeNode		*node,
180 									 GTypeFlags		 flags);
181 static	      void			type_data_make_W		(TypeNode		*node,
182 									 const GTypeInfo	*info,
183 									 const GTypeValueTable	*value_table);
184 static inline void			type_data_ref_Wm		(TypeNode		*node);
185 static inline void			type_data_unref_U               (TypeNode		*node,
186 									 gboolean		 uncached);
187 static void				type_data_last_unref_Wm		(TypeNode *              node,
188 									 gboolean		 uncached);
189 static inline gpointer			type_get_qdata_L		(TypeNode		*node,
190 									 GQuark			 quark);
191 static inline void			type_set_qdata_W		(TypeNode		*node,
192 									 GQuark			 quark,
193 									 gpointer		 data);
194 static IFaceHolder*			type_iface_peek_holder_L	(TypeNode		*iface,
195 									 GType			 instance_type);
196 static gboolean                         type_iface_vtable_base_init_Wm  (TypeNode               *iface,
197                                                                          TypeNode               *node);
198 static void                             type_iface_vtable_iface_init_Wm (TypeNode               *iface,
199                                                                          TypeNode               *node);
200 static gboolean				type_node_is_a_L		(TypeNode		*node,
201 									 TypeNode		*iface_node);
202 
203 
204 /* --- enumeration --- */
205 
206 /* The InitState enumeration is used to track the progress of initializing
207  * both classes and interface vtables. Keeping the state of initialization
208  * is necessary to handle new interfaces being added while we are initializing
209  * the class or other interfaces.
210  */
211 typedef enum
212 {
213   UNINITIALIZED,
214   BASE_CLASS_INIT,
215   BASE_IFACE_INIT,
216   CLASS_INIT,
217   IFACE_INIT,
218   INITIALIZED
219 } InitState;
220 
221 /* --- structures --- */
222 struct _TypeNode
223 {
224   guint        ref_count;  /* (atomic) */
225 #ifdef G_ENABLE_DEBUG
226   guint        instance_count;  /* (atomic) */
227 #endif
228   GTypePlugin *plugin;
229   guint        n_children; /* writable with lock */
230   guint        n_supers : 8;
231   guint        n_prerequisites : 9;
232   guint        is_classed : 1;
233   guint        is_instantiatable : 1;
234   guint        mutatable_check_cache : 1;	/* combines some common path checks */
235   GType       *children; /* writable with lock */
236   TypeData    *data;
237   GQuark       qname;
238   GData       *global_gdata;
239   union {
240     GAtomicArray iface_entries;		/* for !iface types */
241     GAtomicArray offsets;
242   } _prot;
243   GType       *prerequisites;
244   GType        supers[1]; /* flexible array */
245 };
246 
247 #define SIZEOF_BASE_TYPE_NODE()			(G_STRUCT_OFFSET (TypeNode, supers))
248 #define MAX_N_SUPERS				(255)
249 #define MAX_N_CHILDREN				(G_MAXUINT)
250 #define	MAX_N_INTERFACES			(255) /* Limited by offsets being 8 bits */
251 #define	MAX_N_PREREQUISITES			(511)
252 #define NODE_TYPE(node)				(node->supers[0])
253 #define NODE_PARENT_TYPE(node)			(node->supers[1])
254 #define NODE_FUNDAMENTAL_TYPE(node)		(node->supers[node->n_supers])
255 #define NODE_NAME(node)				(g_quark_to_string (node->qname))
256 #define NODE_REFCOUNT(node)                     ((guint) g_atomic_int_get ((int *) &(node)->ref_count))
257 #define	NODE_IS_BOXED(node)			(NODE_FUNDAMENTAL_TYPE (node) == G_TYPE_BOXED)
258 #define	NODE_IS_IFACE(node)			(NODE_FUNDAMENTAL_TYPE (node) == G_TYPE_INTERFACE)
259 #define	CLASSED_NODE_IFACES_ENTRIES(node)	(&(node)->_prot.iface_entries)
260 #define	CLASSED_NODE_IFACES_ENTRIES_LOCKED(node)(G_ATOMIC_ARRAY_GET_LOCKED(CLASSED_NODE_IFACES_ENTRIES((node)), IFaceEntries))
261 #define	IFACE_NODE_N_PREREQUISITES(node)	((node)->n_prerequisites)
262 #define	IFACE_NODE_PREREQUISITES(node)		((node)->prerequisites)
263 #define	iface_node_get_holders_L(node)		((IFaceHolder*) type_get_qdata_L ((node), static_quark_iface_holder))
264 #define	iface_node_set_holders_W(node, holders)	(type_set_qdata_W ((node), static_quark_iface_holder, (holders)))
265 #define	iface_node_get_dependants_array_L(n)	((GType*) type_get_qdata_L ((n), static_quark_dependants_array))
266 #define	iface_node_set_dependants_array_W(n,d)	(type_set_qdata_W ((n), static_quark_dependants_array, (d)))
267 #define	TYPE_ID_MASK				((GType) ((1 << G_TYPE_FUNDAMENTAL_SHIFT) - 1))
268 
269 #define NODE_IS_ANCESTOR(ancestor, node)                                                    \
270         ((ancestor)->n_supers <= (node)->n_supers &&                                        \
271 	 (node)->supers[(node)->n_supers - (ancestor)->n_supers] == NODE_TYPE (ancestor))
272 
273 struct _IFaceHolder
274 {
275   GType           instance_type;
276   GInterfaceInfo *info;
277   GTypePlugin    *plugin;
278   IFaceHolder    *next;
279 };
280 
281 struct _IFaceEntry
282 {
283   GType           iface_type;
284   GTypeInterface *vtable;
285   InitState       init_state;
286 };
287 
288 struct _IFaceEntries {
289   gsize offset_index;
290   IFaceEntry entry[1];
291 };
292 
293 #define IFACE_ENTRIES_HEADER_SIZE (sizeof(IFaceEntries) - sizeof(IFaceEntry))
294 #define IFACE_ENTRIES_N_ENTRIES(_entries) ( (G_ATOMIC_ARRAY_DATA_SIZE((_entries)) - IFACE_ENTRIES_HEADER_SIZE) / sizeof(IFaceEntry) )
295 
296 struct _CommonData
297 {
298   GTypeValueTable  *value_table;
299 };
300 
301 struct _BoxedData
302 {
303   CommonData         data;
304   GBoxedCopyFunc     copy_func;
305   GBoxedFreeFunc     free_func;
306 };
307 
308 struct _IFaceData
309 {
310   CommonData         common;
311   guint16            vtable_size;
312   GBaseInitFunc      vtable_init_base;
313   GBaseFinalizeFunc  vtable_finalize_base;
314   GClassInitFunc     dflt_init;
315   GClassFinalizeFunc dflt_finalize;
316   gconstpointer      dflt_data;
317   gpointer           dflt_vtable;
318 };
319 
320 struct _ClassData
321 {
322   CommonData         common;
323   guint16            class_size;
324   guint16            class_private_size;
325   int                init_state;  /* (atomic) - g_type_class_ref reads it unlocked */
326   GBaseInitFunc      class_init_base;
327   GBaseFinalizeFunc  class_finalize_base;
328   GClassInitFunc     class_init;
329   GClassFinalizeFunc class_finalize;
330   gconstpointer      class_data;
331   gpointer           class;
332 };
333 
334 struct _InstanceData
335 {
336   CommonData         common;
337   guint16            class_size;
338   guint16            class_private_size;
339   int                init_state;  /* (atomic) - g_type_class_ref reads it unlocked */
340   GBaseInitFunc      class_init_base;
341   GBaseFinalizeFunc  class_finalize_base;
342   GClassInitFunc     class_init;
343   GClassFinalizeFunc class_finalize;
344   gconstpointer      class_data;
345   gpointer           class;
346   guint16            instance_size;
347   guint16            private_size;
348   guint16            n_preallocs;
349   GInstanceInitFunc  instance_init;
350 };
351 
352 union _TypeData
353 {
354   CommonData         common;
355   BoxedData          boxed;
356   IFaceData          iface;
357   ClassData          class;
358   InstanceData       instance;
359 };
360 
361 typedef struct {
362   gpointer            cache_data;
363   GTypeClassCacheFunc cache_func;
364 } ClassCacheFunc;
365 
366 typedef struct {
367   gpointer                check_data;
368   GTypeInterfaceCheckFunc check_func;
369 } IFaceCheckFunc;
370 
371 
372 /* --- variables --- */
373 static GRWLock         type_rw_lock;
374 static GRecMutex       class_init_rec_mutex;
375 static guint           static_n_class_cache_funcs = 0;
376 static ClassCacheFunc *static_class_cache_funcs = NULL;
377 static guint           static_n_iface_check_funcs = 0;
378 static IFaceCheckFunc *static_iface_check_funcs = NULL;
379 static GQuark          static_quark_type_flags = 0;
380 static GQuark          static_quark_iface_holder = 0;
381 static GQuark          static_quark_dependants_array = 0;
382 static guint           type_registration_serial = 0;
383 
384 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
385 GTypeDebugFlags	       _g_type_debug_flags = 0;
386 G_GNUC_END_IGNORE_DEPRECATIONS
387 
388 /* --- type nodes --- */
389 static GHashTable       *static_type_nodes_ht = NULL;
390 static TypeNode		*static_fundamental_type_nodes[(G_TYPE_FUNDAMENTAL_MAX >> G_TYPE_FUNDAMENTAL_SHIFT) + 1] = { NULL, };
391 static GType		 static_fundamental_next = G_TYPE_RESERVED_USER_FIRST;
392 
393 static inline TypeNode*
lookup_type_node_I(GType utype)394 lookup_type_node_I (GType utype)
395 {
396   if (utype > G_TYPE_FUNDAMENTAL_MAX)
397     return (TypeNode*) (utype & ~TYPE_ID_MASK);
398   else
399     return static_fundamental_type_nodes[utype >> G_TYPE_FUNDAMENTAL_SHIFT];
400 }
401 
402 /**
403  * g_type_get_type_registration_serial:
404  *
405  * Returns an opaque serial number that represents the state of the set
406  * of registered types. Any time a type is registered this serial changes,
407  * which means you can cache information based on type lookups (such as
408  * g_type_from_name()) and know if the cache is still valid at a later
409  * time by comparing the current serial with the one at the type lookup.
410  *
411  * Since: 2.36
412  *
413  * Returns: An unsigned int, representing the state of type registrations
414  */
415 guint
g_type_get_type_registration_serial(void)416 g_type_get_type_registration_serial (void)
417 {
418   return (guint)g_atomic_int_get ((gint *)&type_registration_serial);
419 }
420 
421 static TypeNode*
type_node_any_new_W(TypeNode * pnode,GType ftype,const gchar * name,GTypePlugin * plugin,GTypeFundamentalFlags type_flags)422 type_node_any_new_W (TypeNode             *pnode,
423 		     GType                 ftype,
424 		     const gchar          *name,
425 		     GTypePlugin          *plugin,
426 		     GTypeFundamentalFlags type_flags)
427 {
428   guint n_supers;
429   GType type;
430   TypeNode *node;
431   guint i, node_size = 0;
432 
433   n_supers = pnode ? pnode->n_supers + 1 : 0;
434 
435   if (!pnode)
436     node_size += SIZEOF_FUNDAMENTAL_INFO;	      /* fundamental type info */
437   node_size += SIZEOF_BASE_TYPE_NODE ();	      /* TypeNode structure */
438   node_size += (sizeof (GType) * (1 + n_supers + 1)); /* self + ancestors + (0) for ->supers[] */
439   node = g_malloc0 (node_size);
440   if (!pnode)					      /* offset fundamental types */
441     {
442       node = G_STRUCT_MEMBER_P (node, SIZEOF_FUNDAMENTAL_INFO);
443       static_fundamental_type_nodes[ftype >> G_TYPE_FUNDAMENTAL_SHIFT] = node;
444       type = ftype;
445 
446 #if ENABLE_VALGRIND
447       VALGRIND_MALLOCLIKE_BLOCK (node, node_size - SIZEOF_FUNDAMENTAL_INFO, FALSE, TRUE);
448 #endif
449     }
450   else
451     type = (GType) node;
452 
453   g_assert ((type & TYPE_ID_MASK) == 0);
454 
455   node->n_supers = n_supers;
456   if (!pnode)
457     {
458       node->supers[0] = type;
459       node->supers[1] = 0;
460 
461       node->is_classed = (type_flags & G_TYPE_FLAG_CLASSED) != 0;
462       node->is_instantiatable = (type_flags & G_TYPE_FLAG_INSTANTIATABLE) != 0;
463 
464       if (NODE_IS_IFACE (node))
465 	{
466           IFACE_NODE_N_PREREQUISITES (node) = 0;
467 	  IFACE_NODE_PREREQUISITES (node) = NULL;
468 	}
469       else
470 	_g_atomic_array_init (CLASSED_NODE_IFACES_ENTRIES (node));
471     }
472   else
473     {
474       node->supers[0] = type;
475       memcpy (node->supers + 1, pnode->supers, sizeof (GType) * (1 + pnode->n_supers + 1));
476 
477       node->is_classed = pnode->is_classed;
478       node->is_instantiatable = pnode->is_instantiatable;
479 
480       if (NODE_IS_IFACE (node))
481 	{
482 	  IFACE_NODE_N_PREREQUISITES (node) = 0;
483 	  IFACE_NODE_PREREQUISITES (node) = NULL;
484 	}
485       else
486 	{
487 	  guint j;
488 	  IFaceEntries *entries;
489 
490 	  entries = _g_atomic_array_copy (CLASSED_NODE_IFACES_ENTRIES (pnode),
491 					  IFACE_ENTRIES_HEADER_SIZE,
492 					  0);
493 	  if (entries)
494 	    {
495 	      for (j = 0; j < IFACE_ENTRIES_N_ENTRIES (entries); j++)
496 		{
497 		  entries->entry[j].vtable = NULL;
498 		  entries->entry[j].init_state = UNINITIALIZED;
499 		}
500 	      _g_atomic_array_update (CLASSED_NODE_IFACES_ENTRIES (node),
501 				      entries);
502 	    }
503 	}
504 
505       i = pnode->n_children++;
506       pnode->children = g_renew (GType, pnode->children, pnode->n_children);
507       pnode->children[i] = type;
508     }
509 
510   TRACE(GOBJECT_TYPE_NEW(name, node->supers[1], type));
511 
512   node->plugin = plugin;
513   node->n_children = 0;
514   node->children = NULL;
515   node->data = NULL;
516   node->qname = g_quark_from_string (name);
517   node->global_gdata = NULL;
518   g_hash_table_insert (static_type_nodes_ht,
519 		       (gpointer) g_quark_to_string (node->qname),
520 		       (gpointer) type);
521 
522   g_atomic_int_inc ((gint *)&type_registration_serial);
523 
524   return node;
525 }
526 
527 static inline GTypeFundamentalInfo*
type_node_fundamental_info_I(TypeNode * node)528 type_node_fundamental_info_I (TypeNode *node)
529 {
530   GType ftype = NODE_FUNDAMENTAL_TYPE (node);
531 
532   if (ftype != NODE_TYPE (node))
533     node = lookup_type_node_I (ftype);
534 
535   return node ? G_STRUCT_MEMBER_P (node, -SIZEOF_FUNDAMENTAL_INFO) : NULL;
536 }
537 
538 static TypeNode*
type_node_fundamental_new_W(GType ftype,const gchar * name,GTypeFundamentalFlags type_flags)539 type_node_fundamental_new_W (GType                 ftype,
540 			     const gchar          *name,
541 			     GTypeFundamentalFlags type_flags)
542 {
543   GTypeFundamentalInfo *finfo;
544   TypeNode *node;
545 
546   g_assert ((ftype & TYPE_ID_MASK) == 0);
547   g_assert (ftype <= G_TYPE_FUNDAMENTAL_MAX);
548 
549   if (ftype >> G_TYPE_FUNDAMENTAL_SHIFT == static_fundamental_next)
550     static_fundamental_next++;
551 
552   type_flags &= TYPE_FUNDAMENTAL_FLAG_MASK;
553 
554   node = type_node_any_new_W (NULL, ftype, name, NULL, type_flags);
555 
556   finfo = type_node_fundamental_info_I (node);
557   finfo->type_flags = type_flags;
558 
559   return node;
560 }
561 
562 static TypeNode*
type_node_new_W(TypeNode * pnode,const gchar * name,GTypePlugin * plugin)563 type_node_new_W (TypeNode    *pnode,
564 		 const gchar *name,
565 		 GTypePlugin *plugin)
566 
567 {
568   g_assert (pnode);
569   g_assert (pnode->n_supers < MAX_N_SUPERS);
570   g_assert (pnode->n_children < MAX_N_CHILDREN);
571 
572   return type_node_any_new_W (pnode, NODE_FUNDAMENTAL_TYPE (pnode), name, plugin, 0);
573 }
574 
575 static inline IFaceEntry*
lookup_iface_entry_I(IFaceEntries * entries,TypeNode * iface_node)576 lookup_iface_entry_I (IFaceEntries *entries,
577                       TypeNode     *iface_node)
578 {
579   guint8 *offsets;
580   gsize offset_index;
581   IFaceEntry *check;
582   gsize index;
583   IFaceEntry *entry;
584 
585   if (entries == NULL)
586     return NULL;
587 
588   G_ATOMIC_ARRAY_DO_TRANSACTION
589     (&iface_node->_prot.offsets, guint8,
590 
591      entry = NULL;
592      offsets = transaction_data;
593      offset_index = entries->offset_index;
594      if (offsets != NULL &&
595 	 offset_index < G_ATOMIC_ARRAY_DATA_SIZE(offsets))
596        {
597 	 index = offsets[offset_index];
598 	 if (index > 0)
599 	   {
600 	     /* zero means unset, subtract one to get real index */
601 	     index -= 1;
602 
603 	     if (index < IFACE_ENTRIES_N_ENTRIES (entries))
604 	       {
605 		 check = (IFaceEntry *)&entries->entry[index];
606 		 if (check->iface_type == NODE_TYPE (iface_node))
607 		   entry = check;
608 	       }
609 	   }
610        }
611      );
612 
613  return entry;
614 }
615 
616 static inline IFaceEntry*
type_lookup_iface_entry_L(TypeNode * node,TypeNode * iface_node)617 type_lookup_iface_entry_L (TypeNode *node,
618 			   TypeNode *iface_node)
619 {
620   if (!NODE_IS_IFACE (iface_node))
621     return NULL;
622 
623   return lookup_iface_entry_I (CLASSED_NODE_IFACES_ENTRIES_LOCKED (node),
624 			       iface_node);
625 }
626 
627 
628 static inline gboolean
type_lookup_iface_vtable_I(TypeNode * node,TypeNode * iface_node,gpointer * vtable_ptr)629 type_lookup_iface_vtable_I (TypeNode *node,
630 			    TypeNode *iface_node,
631 			    gpointer *vtable_ptr)
632 {
633   IFaceEntry *entry;
634   gboolean res;
635 
636   if (!NODE_IS_IFACE (iface_node))
637     {
638       if (vtable_ptr)
639 	*vtable_ptr = NULL;
640       return FALSE;
641     }
642 
643   G_ATOMIC_ARRAY_DO_TRANSACTION
644     (CLASSED_NODE_IFACES_ENTRIES (node), IFaceEntries,
645 
646      entry = lookup_iface_entry_I (transaction_data, iface_node);
647      res = entry != NULL;
648      if (vtable_ptr)
649        {
650 	 if (entry)
651 	   *vtable_ptr = entry->vtable;
652 	 else
653 	   *vtable_ptr = NULL;
654        }
655      );
656 
657   return res;
658 }
659 
660 static inline gboolean
type_lookup_prerequisite_L(TypeNode * iface,GType prerequisite_type)661 type_lookup_prerequisite_L (TypeNode *iface,
662 			    GType     prerequisite_type)
663 {
664   if (NODE_IS_IFACE (iface) && IFACE_NODE_N_PREREQUISITES (iface))
665     {
666       GType *prerequisites = IFACE_NODE_PREREQUISITES (iface) - 1;
667       guint n_prerequisites = IFACE_NODE_N_PREREQUISITES (iface);
668 
669       do
670 	{
671 	  guint i;
672 	  GType *check;
673 
674 	  i = (n_prerequisites + 1) >> 1;
675 	  check = prerequisites + i;
676 	  if (prerequisite_type == *check)
677 	    return TRUE;
678 	  else if (prerequisite_type > *check)
679 	    {
680 	      n_prerequisites -= i;
681 	      prerequisites = check;
682 	    }
683 	  else /* if (prerequisite_type < *check) */
684 	    n_prerequisites = i - 1;
685 	}
686       while (n_prerequisites);
687     }
688   return FALSE;
689 }
690 
691 static const gchar*
type_descriptive_name_I(GType type)692 type_descriptive_name_I (GType type)
693 {
694   if (type)
695     {
696       TypeNode *node = lookup_type_node_I (type);
697 
698       return node ? NODE_NAME (node) : "<unknown>";
699     }
700   else
701     return "<invalid>";
702 }
703 
704 
705 /* --- type consistency checks --- */
706 static gboolean
check_plugin_U(GTypePlugin * plugin,gboolean need_complete_type_info,gboolean need_complete_interface_info,const gchar * type_name)707 check_plugin_U (GTypePlugin *plugin,
708 		gboolean     need_complete_type_info,
709 		gboolean     need_complete_interface_info,
710 		const gchar *type_name)
711 {
712   /* G_IS_TYPE_PLUGIN() and G_TYPE_PLUGIN_GET_CLASS() are external calls: _U
713    */
714   if (!plugin)
715     {
716       g_warning ("plugin handle for type '%s' is NULL",
717 		 type_name);
718       return FALSE;
719     }
720   if (!G_IS_TYPE_PLUGIN (plugin))
721     {
722       g_warning ("plugin pointer (%p) for type '%s' is invalid",
723 		 plugin, type_name);
724       return FALSE;
725     }
726   if (need_complete_type_info && !G_TYPE_PLUGIN_GET_CLASS (plugin)->complete_type_info)
727     {
728       g_warning ("plugin for type '%s' has no complete_type_info() implementation",
729 		 type_name);
730       return FALSE;
731     }
732   if (need_complete_interface_info && !G_TYPE_PLUGIN_GET_CLASS (plugin)->complete_interface_info)
733     {
734       g_warning ("plugin for type '%s' has no complete_interface_info() implementation",
735 		 type_name);
736       return FALSE;
737     }
738   return TRUE;
739 }
740 
741 static gboolean
check_type_name_I(const gchar * type_name)742 check_type_name_I (const gchar *type_name)
743 {
744   static const gchar extra_chars[] = "-_+";
745   const gchar *p = type_name;
746   gboolean name_valid;
747 
748   if (!type_name[0] || !type_name[1] || !type_name[2])
749     {
750       g_warning ("type name '%s' is too short", type_name);
751       return FALSE;
752     }
753   /* check the first letter */
754   name_valid = (p[0] >= 'A' && p[0] <= 'Z') || (p[0] >= 'a' && p[0] <= 'z') || p[0] == '_';
755   for (p = type_name + 1; *p; p++)
756     name_valid &= ((p[0] >= 'A' && p[0] <= 'Z') ||
757 		   (p[0] >= 'a' && p[0] <= 'z') ||
758 		   (p[0] >= '0' && p[0] <= '9') ||
759 		   strchr (extra_chars, p[0]));
760   if (!name_valid)
761     {
762       g_warning ("type name '%s' contains invalid characters", type_name);
763       return FALSE;
764     }
765   if (g_type_from_name (type_name))
766     {
767       g_warning ("cannot register existing type '%s'", type_name);
768       return FALSE;
769     }
770 
771   return TRUE;
772 }
773 
774 static gboolean
check_derivation_I(GType parent_type,const gchar * type_name)775 check_derivation_I (GType        parent_type,
776 		    const gchar *type_name)
777 {
778   TypeNode *pnode;
779   GTypeFundamentalInfo* finfo;
780 
781   pnode = lookup_type_node_I (parent_type);
782   if (!pnode)
783     {
784       g_warning ("cannot derive type '%s' from invalid parent type '%s'",
785 		 type_name,
786 		 type_descriptive_name_I (parent_type));
787       return FALSE;
788     }
789   finfo = type_node_fundamental_info_I (pnode);
790   /* ensure flat derivability */
791   if (!(finfo->type_flags & G_TYPE_FLAG_DERIVABLE))
792     {
793       g_warning ("cannot derive '%s' from non-derivable parent type '%s'",
794 		 type_name,
795 		 NODE_NAME (pnode));
796       return FALSE;
797     }
798   /* ensure deep derivability */
799   if (parent_type != NODE_FUNDAMENTAL_TYPE (pnode) &&
800       !(finfo->type_flags & G_TYPE_FLAG_DEEP_DERIVABLE))
801     {
802       g_warning ("cannot derive '%s' from non-fundamental parent type '%s'",
803 		 type_name,
804 		 NODE_NAME (pnode));
805       return FALSE;
806     }
807 
808   return TRUE;
809 }
810 
811 static gboolean
check_collect_format_I(const gchar * collect_format)812 check_collect_format_I (const gchar *collect_format)
813 {
814   const gchar *p = collect_format;
815   gchar valid_format[] = { G_VALUE_COLLECT_INT, G_VALUE_COLLECT_LONG,
816 			   G_VALUE_COLLECT_INT64, G_VALUE_COLLECT_DOUBLE,
817 			   G_VALUE_COLLECT_POINTER, 0 };
818 
819   while (*p)
820     if (!strchr (valid_format, *p++))
821       return FALSE;
822   return p - collect_format <= G_VALUE_COLLECT_FORMAT_MAX_LENGTH;
823 }
824 
825 static gboolean
check_value_table_I(const gchar * type_name,const GTypeValueTable * value_table)826 check_value_table_I (const gchar           *type_name,
827 		     const GTypeValueTable *value_table)
828 {
829   if (!value_table)
830     return FALSE;
831   else if (value_table->value_init == NULL)
832     {
833       if (value_table->value_free || value_table->value_copy ||
834 	  value_table->value_peek_pointer ||
835 	  value_table->collect_format || value_table->collect_value ||
836 	  value_table->lcopy_format || value_table->lcopy_value)
837 	g_warning ("cannot handle uninitializable values of type '%s'",
838 		   type_name);
839       return FALSE;
840     }
841   else /* value_table->value_init != NULL */
842     {
843       if (!value_table->value_free)
844 	{
845 	  /* +++ optional +++
846 	   * g_warning ("missing 'value_free()' for type '%s'", type_name);
847 	   * return FALSE;
848 	   */
849 	}
850       if (!value_table->value_copy)
851 	{
852 	  g_warning ("missing 'value_copy()' for type '%s'", type_name);
853 	  return FALSE;
854 	}
855       if ((value_table->collect_format || value_table->collect_value) &&
856 	  (!value_table->collect_format || !value_table->collect_value))
857 	{
858 	  g_warning ("one of 'collect_format' and 'collect_value()' is unspecified for type '%s'",
859 		     type_name);
860 	  return FALSE;
861 	}
862       if (value_table->collect_format && !check_collect_format_I (value_table->collect_format))
863 	{
864 	  g_warning ("the '%s' specification for type '%s' is too long or invalid",
865 		     "collect_format",
866 		     type_name);
867 	  return FALSE;
868 	}
869       if ((value_table->lcopy_format || value_table->lcopy_value) &&
870 	  (!value_table->lcopy_format || !value_table->lcopy_value))
871 	{
872 	  g_warning ("one of 'lcopy_format' and 'lcopy_value()' is unspecified for type '%s'",
873 		     type_name);
874 	  return FALSE;
875 	}
876       if (value_table->lcopy_format && !check_collect_format_I (value_table->lcopy_format))
877 	{
878 	  g_warning ("the '%s' specification for type '%s' is too long or invalid",
879 		     "lcopy_format",
880 		     type_name);
881 	  return FALSE;
882 	}
883     }
884   return TRUE;
885 }
886 
887 static gboolean
check_type_info_I(TypeNode * pnode,GType ftype,const gchar * type_name,const GTypeInfo * info)888 check_type_info_I (TypeNode        *pnode,
889 		   GType            ftype,
890 		   const gchar     *type_name,
891 		   const GTypeInfo *info)
892 {
893   GTypeFundamentalInfo *finfo = type_node_fundamental_info_I (lookup_type_node_I (ftype));
894   gboolean is_interface = ftype == G_TYPE_INTERFACE;
895 
896   g_assert (ftype <= G_TYPE_FUNDAMENTAL_MAX && !(ftype & TYPE_ID_MASK));
897 
898   /* check instance members */
899   if (!(finfo->type_flags & G_TYPE_FLAG_INSTANTIATABLE) &&
900       (info->instance_size || info->n_preallocs || info->instance_init))
901     {
902       if (pnode)
903 	g_warning ("cannot instantiate '%s', derived from non-instantiatable parent type '%s'",
904 		   type_name,
905 		   NODE_NAME (pnode));
906       else
907 	g_warning ("cannot instantiate '%s' as non-instantiatable fundamental",
908 		   type_name);
909       return FALSE;
910     }
911   /* check class & interface members */
912   if (!((finfo->type_flags & G_TYPE_FLAG_CLASSED) || is_interface) &&
913       (info->class_init || info->class_finalize || info->class_data ||
914        info->class_size || info->base_init || info->base_finalize))
915     {
916       if (pnode)
917 	g_warning ("cannot create class for '%s', derived from non-classed parent type '%s'",
918 		   type_name,
919                    NODE_NAME (pnode));
920       else
921 	g_warning ("cannot create class for '%s' as non-classed fundamental",
922 		   type_name);
923       return FALSE;
924     }
925   /* check interface size */
926   if (is_interface && info->class_size < sizeof (GTypeInterface))
927     {
928       g_warning ("specified interface size for type '%s' is smaller than 'GTypeInterface' size",
929 		 type_name);
930       return FALSE;
931     }
932   /* check class size */
933   if (finfo->type_flags & G_TYPE_FLAG_CLASSED)
934     {
935       if (info->class_size < sizeof (GTypeClass))
936 	{
937 	  g_warning ("specified class size for type '%s' is smaller than 'GTypeClass' size",
938 		     type_name);
939 	  return FALSE;
940 	}
941       if (pnode && info->class_size < pnode->data->class.class_size)
942 	{
943 	  g_warning ("specified class size for type '%s' is smaller "
944 		     "than the parent type's '%s' class size",
945 		     type_name,
946 		     NODE_NAME (pnode));
947 	  return FALSE;
948 	}
949     }
950   /* check instance size */
951   if (finfo->type_flags & G_TYPE_FLAG_INSTANTIATABLE)
952     {
953       if (info->instance_size < sizeof (GTypeInstance))
954 	{
955 	  g_warning ("specified instance size for type '%s' is smaller than 'GTypeInstance' size",
956 		     type_name);
957 	  return FALSE;
958 	}
959       if (pnode && info->instance_size < pnode->data->instance.instance_size)
960 	{
961 	  g_warning ("specified instance size for type '%s' is smaller "
962 		     "than the parent type's '%s' instance size",
963 		     type_name,
964 		     NODE_NAME (pnode));
965 	  return FALSE;
966 	}
967     }
968 
969   return TRUE;
970 }
971 
972 static TypeNode*
find_conforming_child_type_L(TypeNode * pnode,TypeNode * iface)973 find_conforming_child_type_L (TypeNode *pnode,
974 			      TypeNode *iface)
975 {
976   TypeNode *node = NULL;
977   guint i;
978 
979   if (type_lookup_iface_entry_L (pnode, iface))
980     return pnode;
981 
982   for (i = 0; i < pnode->n_children && !node; i++)
983     node = find_conforming_child_type_L (lookup_type_node_I (pnode->children[i]), iface);
984 
985   return node;
986 }
987 
988 static gboolean
check_add_interface_L(GType instance_type,GType iface_type)989 check_add_interface_L (GType instance_type,
990 		       GType iface_type)
991 {
992   TypeNode *node = lookup_type_node_I (instance_type);
993   TypeNode *iface = lookup_type_node_I (iface_type);
994   IFaceEntry *entry;
995   TypeNode *tnode;
996   GType *prerequisites;
997   guint i;
998 
999 
1000   if (!node || !node->is_instantiatable)
1001     {
1002       g_warning ("cannot add interfaces to invalid (non-instantiatable) type '%s'",
1003 		 type_descriptive_name_I (instance_type));
1004       return FALSE;
1005     }
1006   if (!iface || !NODE_IS_IFACE (iface))
1007     {
1008       g_warning ("cannot add invalid (non-interface) type '%s' to type '%s'",
1009 		 type_descriptive_name_I (iface_type),
1010 		 NODE_NAME (node));
1011       return FALSE;
1012     }
1013   if (node->data && node->data->class.class)
1014     {
1015       g_warning ("attempting to add an interface (%s) to class (%s) after class_init",
1016                  NODE_NAME (iface), NODE_NAME (node));
1017       return FALSE;
1018     }
1019   tnode = lookup_type_node_I (NODE_PARENT_TYPE (iface));
1020   if (NODE_PARENT_TYPE (tnode) && !type_lookup_iface_entry_L (node, tnode))
1021     {
1022       /* 2001/7/31:timj: erk, i guess this warning is junk as interface derivation is flat */
1023       g_warning ("cannot add sub-interface '%s' to type '%s' which does not conform to super-interface '%s'",
1024 		 NODE_NAME (iface),
1025 		 NODE_NAME (node),
1026 		 NODE_NAME (tnode));
1027       return FALSE;
1028     }
1029   /* allow overriding of interface type introduced for parent type */
1030   entry = type_lookup_iface_entry_L (node, iface);
1031   if (entry && entry->vtable == NULL && !type_iface_peek_holder_L (iface, NODE_TYPE (node)))
1032     {
1033       /* ok, we do conform to this interface already, but the interface vtable was not
1034        * yet initialized, and we just conform to the interface because it got added to
1035        * one of our parents. so we allow overriding of holder info here.
1036        */
1037       return TRUE;
1038     }
1039   /* check whether one of our children already conforms (or whether the interface
1040    * got added to this node already)
1041    */
1042   tnode = find_conforming_child_type_L (node, iface);  /* tnode is_a node */
1043   if (tnode)
1044     {
1045       g_warning ("cannot add interface type '%s' to type '%s', since type '%s' already conforms to interface",
1046 		 NODE_NAME (iface),
1047 		 NODE_NAME (node),
1048 		 NODE_NAME (tnode));
1049       return FALSE;
1050     }
1051   prerequisites = IFACE_NODE_PREREQUISITES (iface);
1052   for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++)
1053     {
1054       tnode = lookup_type_node_I (prerequisites[i]);
1055       if (!type_node_is_a_L (node, tnode))
1056 	{
1057 	  g_warning ("cannot add interface type '%s' to type '%s' which does not conform to prerequisite '%s'",
1058 		     NODE_NAME (iface),
1059 		     NODE_NAME (node),
1060 		     NODE_NAME (tnode));
1061 	  return FALSE;
1062 	}
1063     }
1064   return TRUE;
1065 }
1066 
1067 static gboolean
check_interface_info_I(TypeNode * iface,GType instance_type,const GInterfaceInfo * info)1068 check_interface_info_I (TypeNode             *iface,
1069 			GType                 instance_type,
1070 			const GInterfaceInfo *info)
1071 {
1072   if ((info->interface_finalize || info->interface_data) && !info->interface_init)
1073     {
1074       g_warning ("interface type '%s' for type '%s' comes without initializer",
1075 		 NODE_NAME (iface),
1076 		 type_descriptive_name_I (instance_type));
1077       return FALSE;
1078     }
1079 
1080   return TRUE;
1081 }
1082 
1083 /* --- type info (type node data) --- */
1084 static void
type_data_make_W(TypeNode * node,const GTypeInfo * info,const GTypeValueTable * value_table)1085 type_data_make_W (TypeNode              *node,
1086 		  const GTypeInfo       *info,
1087 		  const GTypeValueTable *value_table)
1088 {
1089   TypeData *data;
1090   GTypeValueTable *vtable = NULL;
1091   guint vtable_size = 0;
1092 
1093   g_assert (node->data == NULL && info != NULL);
1094 
1095   if (!value_table)
1096     {
1097       TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
1098 
1099       if (pnode)
1100 	vtable = pnode->data->common.value_table;
1101       else
1102 	{
1103 	  static const GTypeValueTable zero_vtable = { NULL, };
1104 
1105 	  value_table = &zero_vtable;
1106 	}
1107     }
1108   if (value_table)
1109     {
1110       /* need to setup vtable_size since we have to allocate it with data in one chunk */
1111       vtable_size = sizeof (GTypeValueTable);
1112       if (value_table->collect_format)
1113 	vtable_size += strlen (value_table->collect_format);
1114       if (value_table->lcopy_format)
1115 	vtable_size += strlen (value_table->lcopy_format);
1116       vtable_size += 2;
1117     }
1118 
1119   if (node->is_instantiatable) /* careful, is_instantiatable is also is_classed */
1120     {
1121       TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
1122 
1123       data = g_malloc0 (sizeof (InstanceData) + vtable_size);
1124       if (vtable_size)
1125 	vtable = G_STRUCT_MEMBER_P (data, sizeof (InstanceData));
1126       data->instance.class_size = info->class_size;
1127       data->instance.class_init_base = info->base_init;
1128       data->instance.class_finalize_base = info->base_finalize;
1129       data->instance.class_init = info->class_init;
1130       data->instance.class_finalize = info->class_finalize;
1131       data->instance.class_data = info->class_data;
1132       data->instance.class = NULL;
1133       data->instance.init_state = UNINITIALIZED;
1134       data->instance.instance_size = info->instance_size;
1135       /* We'll set the final value for data->instance.private size
1136        * after the parent class has been initialized
1137        */
1138       data->instance.private_size = 0;
1139       data->instance.class_private_size = 0;
1140       if (pnode)
1141         data->instance.class_private_size = pnode->data->instance.class_private_size;
1142       data->instance.n_preallocs = MIN (info->n_preallocs, 1024);
1143       data->instance.instance_init = info->instance_init;
1144     }
1145   else if (node->is_classed) /* only classed */
1146     {
1147       TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
1148 
1149       data = g_malloc0 (sizeof (ClassData) + vtable_size);
1150       if (vtable_size)
1151 	vtable = G_STRUCT_MEMBER_P (data, sizeof (ClassData));
1152       data->class.class_size = info->class_size;
1153       data->class.class_init_base = info->base_init;
1154       data->class.class_finalize_base = info->base_finalize;
1155       data->class.class_init = info->class_init;
1156       data->class.class_finalize = info->class_finalize;
1157       data->class.class_data = info->class_data;
1158       data->class.class = NULL;
1159       data->class.class_private_size = 0;
1160       if (pnode)
1161         data->class.class_private_size = pnode->data->class.class_private_size;
1162       data->class.init_state = UNINITIALIZED;
1163     }
1164   else if (NODE_IS_IFACE (node))
1165     {
1166       data = g_malloc0 (sizeof (IFaceData) + vtable_size);
1167       if (vtable_size)
1168 	vtable = G_STRUCT_MEMBER_P (data, sizeof (IFaceData));
1169       data->iface.vtable_size = info->class_size;
1170       data->iface.vtable_init_base = info->base_init;
1171       data->iface.vtable_finalize_base = info->base_finalize;
1172       data->iface.dflt_init = info->class_init;
1173       data->iface.dflt_finalize = info->class_finalize;
1174       data->iface.dflt_data = info->class_data;
1175       data->iface.dflt_vtable = NULL;
1176     }
1177   else if (NODE_IS_BOXED (node))
1178     {
1179       data = g_malloc0 (sizeof (BoxedData) + vtable_size);
1180       if (vtable_size)
1181 	vtable = G_STRUCT_MEMBER_P (data, sizeof (BoxedData));
1182     }
1183   else
1184     {
1185       data = g_malloc0 (sizeof (CommonData) + vtable_size);
1186       if (vtable_size)
1187 	vtable = G_STRUCT_MEMBER_P (data, sizeof (CommonData));
1188     }
1189 
1190   node->data = data;
1191 
1192   if (vtable_size)
1193     {
1194       gchar *p;
1195 
1196       /* we allocate the vtable and its strings together with the type data, so
1197        * children can take over their parent's vtable pointer, and we don't
1198        * need to worry freeing it or not when the child data is destroyed
1199        */
1200       *vtable = *value_table;
1201       p = G_STRUCT_MEMBER_P (vtable, sizeof (*vtable));
1202       p[0] = 0;
1203       vtable->collect_format = p;
1204       if (value_table->collect_format)
1205 	{
1206 	  strcat (p, value_table->collect_format);
1207 	  p += strlen (value_table->collect_format);
1208 	}
1209       p++;
1210       p[0] = 0;
1211       vtable->lcopy_format = p;
1212       if (value_table->lcopy_format)
1213 	strcat  (p, value_table->lcopy_format);
1214     }
1215   node->data->common.value_table = vtable;
1216   node->mutatable_check_cache = (node->data->common.value_table->value_init != NULL &&
1217 				 !((G_TYPE_FLAG_VALUE_ABSTRACT | G_TYPE_FLAG_ABSTRACT) &
1218 				   GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags))));
1219 
1220   g_assert (node->data->common.value_table != NULL); /* paranoid */
1221 
1222   g_atomic_int_set ((int *) &node->ref_count, 1);
1223 }
1224 
1225 static inline void
type_data_ref_Wm(TypeNode * node)1226 type_data_ref_Wm (TypeNode *node)
1227 {
1228   if (!node->data)
1229     {
1230       TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
1231       GTypeInfo tmp_info;
1232       GTypeValueTable tmp_value_table;
1233 
1234       g_assert (node->plugin != NULL);
1235 
1236       if (pnode)
1237 	{
1238 	  type_data_ref_Wm (pnode);
1239 	  if (node->data)
1240 	    INVALID_RECURSION ("g_type_plugin_*", node->plugin, NODE_NAME (node));
1241 	}
1242 
1243       memset (&tmp_info, 0, sizeof (tmp_info));
1244       memset (&tmp_value_table, 0, sizeof (tmp_value_table));
1245 
1246       G_WRITE_UNLOCK (&type_rw_lock);
1247       g_type_plugin_use (node->plugin);
1248       g_type_plugin_complete_type_info (node->plugin, NODE_TYPE (node), &tmp_info, &tmp_value_table);
1249       G_WRITE_LOCK (&type_rw_lock);
1250       if (node->data)
1251 	INVALID_RECURSION ("g_type_plugin_*", node->plugin, NODE_NAME (node));
1252 
1253       check_type_info_I (pnode, NODE_FUNDAMENTAL_TYPE (node), NODE_NAME (node), &tmp_info);
1254       type_data_make_W (node, &tmp_info,
1255 			check_value_table_I (NODE_NAME (node),
1256 					     &tmp_value_table) ? &tmp_value_table : NULL);
1257     }
1258   else
1259     {
1260       g_assert (NODE_REFCOUNT (node) > 0);
1261 
1262       g_atomic_int_inc ((int *) &node->ref_count);
1263     }
1264 }
1265 
1266 static inline gboolean
type_data_ref_U(TypeNode * node)1267 type_data_ref_U (TypeNode *node)
1268 {
1269   guint current;
1270 
1271   do {
1272     current = NODE_REFCOUNT (node);
1273 
1274     if (current < 1)
1275       return FALSE;
1276   } while (!g_atomic_int_compare_and_exchange ((int *) &node->ref_count, current, current + 1));
1277 
1278   return TRUE;
1279 }
1280 
1281 static gboolean
iface_node_has_available_offset_L(TypeNode * iface_node,gsize offset,int for_index)1282 iface_node_has_available_offset_L (TypeNode *iface_node,
1283 				   gsize offset,
1284 				   int for_index)
1285 {
1286   guint8 *offsets;
1287 
1288   offsets = G_ATOMIC_ARRAY_GET_LOCKED (&iface_node->_prot.offsets, guint8);
1289   if (offsets == NULL)
1290     return TRUE;
1291 
1292   if (G_ATOMIC_ARRAY_DATA_SIZE (offsets) <= offset)
1293     return TRUE;
1294 
1295   if (offsets[offset] == 0 ||
1296       offsets[offset] == for_index+1)
1297     return TRUE;
1298 
1299   return FALSE;
1300 }
1301 
1302 static gsize
find_free_iface_offset_L(IFaceEntries * entries)1303 find_free_iface_offset_L (IFaceEntries *entries)
1304 {
1305   IFaceEntry *entry;
1306   TypeNode *iface_node;
1307   gsize offset;
1308   int i;
1309   int n_entries;
1310 
1311   n_entries = IFACE_ENTRIES_N_ENTRIES (entries);
1312   offset = 0;
1313   do
1314     {
1315       for (i = 0; i < n_entries; i++)
1316 	{
1317 	  entry = &entries->entry[i];
1318 	  iface_node = lookup_type_node_I (entry->iface_type);
1319 
1320 	  if (!iface_node_has_available_offset_L (iface_node, offset, i))
1321             {
1322               offset++;
1323               break;
1324             }
1325 	}
1326     }
1327   while (i != n_entries);
1328 
1329   return offset;
1330 }
1331 
1332 static void
iface_node_set_offset_L(TypeNode * iface_node,gsize offset,int index)1333 iface_node_set_offset_L (TypeNode *iface_node,
1334 			 gsize offset,
1335 			 int index)
1336 {
1337   guint8 *offsets, *old_offsets;
1338   gsize new_size, old_size;
1339   gsize i;
1340 
1341   old_offsets = G_ATOMIC_ARRAY_GET_LOCKED (&iface_node->_prot.offsets, guint8);
1342   if (old_offsets == NULL)
1343     old_size = 0;
1344   else
1345     {
1346       old_size = G_ATOMIC_ARRAY_DATA_SIZE (old_offsets);
1347       if (offset < old_size &&
1348 	  old_offsets[offset] == index + 1)
1349 	return; /* Already set to this index, return */
1350     }
1351   new_size = MAX (old_size, offset + 1);
1352 
1353   offsets = _g_atomic_array_copy (&iface_node->_prot.offsets,
1354 				  0, new_size - old_size);
1355 
1356   /* Mark new area as unused */
1357   for (i = old_size; i < new_size; i++)
1358     offsets[i] = 0;
1359 
1360   offsets[offset] = index + 1;
1361 
1362   _g_atomic_array_update (&iface_node->_prot.offsets, offsets);
1363 }
1364 
1365 static void
type_node_add_iface_entry_W(TypeNode * node,GType iface_type,IFaceEntry * parent_entry)1366 type_node_add_iface_entry_W (TypeNode   *node,
1367 			     GType       iface_type,
1368                              IFaceEntry *parent_entry)
1369 {
1370   IFaceEntries *entries;
1371   IFaceEntry *entry;
1372   TypeNode *iface_node;
1373   guint i, j;
1374   guint num_entries;
1375 
1376   g_assert (node->is_instantiatable);
1377 
1378   entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node);
1379   if (entries != NULL)
1380     {
1381       num_entries = IFACE_ENTRIES_N_ENTRIES (entries);
1382 
1383       g_assert (num_entries < MAX_N_INTERFACES);
1384 
1385       for (i = 0; i < num_entries; i++)
1386 	{
1387 	  entry = &entries->entry[i];
1388 	  if (entry->iface_type == iface_type)
1389 	    {
1390 	      /* this can happen in two cases:
1391 	       * - our parent type already conformed to iface_type and node
1392 	       *   got its own holder info. here, our children already have
1393 	       *   entries and NULL vtables, since this will only work for
1394 	       *   uninitialized classes.
1395 	       * - an interface type is added to an ancestor after it was
1396 	       *   added to a child type.
1397 	       */
1398 	      if (!parent_entry)
1399 		g_assert (entry->vtable == NULL && entry->init_state == UNINITIALIZED);
1400 	      else
1401 		{
1402 		  /* sick, interface is added to ancestor *after* child type;
1403 		   * nothing todo, the entry and our children were already setup correctly
1404 		   */
1405 		}
1406 	      return;
1407 	    }
1408 	}
1409     }
1410 
1411   entries = _g_atomic_array_copy (CLASSED_NODE_IFACES_ENTRIES (node),
1412 				  IFACE_ENTRIES_HEADER_SIZE,
1413 				  sizeof (IFaceEntry));
1414   num_entries = IFACE_ENTRIES_N_ENTRIES (entries);
1415   i = num_entries - 1;
1416   if (i == 0)
1417     entries->offset_index = 0;
1418   entries->entry[i].iface_type = iface_type;
1419   entries->entry[i].vtable = NULL;
1420   entries->entry[i].init_state = UNINITIALIZED;
1421 
1422   if (parent_entry)
1423     {
1424       if (node->data && g_atomic_int_get (&node->data->class.init_state) >= BASE_IFACE_INIT)
1425         {
1426           entries->entry[i].init_state = INITIALIZED;
1427           entries->entry[i].vtable = parent_entry->vtable;
1428         }
1429     }
1430 
1431   /* Update offsets in iface */
1432   iface_node = lookup_type_node_I (iface_type);
1433 
1434   if (iface_node_has_available_offset_L (iface_node,
1435 					 entries->offset_index,
1436 					 i))
1437     {
1438       iface_node_set_offset_L (iface_node,
1439 			       entries->offset_index, i);
1440     }
1441   else
1442    {
1443       entries->offset_index =
1444 	find_free_iface_offset_L (entries);
1445       for (j = 0; j < IFACE_ENTRIES_N_ENTRIES (entries); j++)
1446 	{
1447 	  entry = &entries->entry[j];
1448 	  iface_node =
1449 	    lookup_type_node_I (entry->iface_type);
1450 	  iface_node_set_offset_L (iface_node,
1451 				   entries->offset_index, j);
1452 	}
1453     }
1454 
1455   _g_atomic_array_update (CLASSED_NODE_IFACES_ENTRIES (node), entries);
1456 
1457   if (parent_entry)
1458     {
1459       for (i = 0; i < node->n_children; i++)
1460         type_node_add_iface_entry_W (lookup_type_node_I (node->children[i]), iface_type, &entries->entry[i]);
1461     }
1462 }
1463 
1464 static void
type_add_interface_Wm(TypeNode * node,TypeNode * iface,const GInterfaceInfo * info,GTypePlugin * plugin)1465 type_add_interface_Wm (TypeNode             *node,
1466                        TypeNode             *iface,
1467                        const GInterfaceInfo *info,
1468                        GTypePlugin          *plugin)
1469 {
1470   IFaceHolder *iholder = g_new0 (IFaceHolder, 1);
1471   IFaceEntry *entry;
1472   guint i;
1473 
1474   g_assert (node->is_instantiatable && NODE_IS_IFACE (iface) && ((info && !plugin) || (!info && plugin)));
1475 
1476   iholder->next = iface_node_get_holders_L (iface);
1477   iface_node_set_holders_W (iface, iholder);
1478   iholder->instance_type = NODE_TYPE (node);
1479   iholder->info = info ? g_memdup2 (info, sizeof (*info)) : NULL;
1480   iholder->plugin = plugin;
1481 
1482   /* create an iface entry for this type */
1483   type_node_add_iface_entry_W (node, NODE_TYPE (iface), NULL);
1484 
1485   /* if the class is already (partly) initialized, we may need to base
1486    * initialize and/or initialize the new interface.
1487    */
1488   if (node->data)
1489     {
1490       InitState class_state = g_atomic_int_get (&node->data->class.init_state);
1491 
1492       if (class_state >= BASE_IFACE_INIT)
1493         type_iface_vtable_base_init_Wm (iface, node);
1494 
1495       if (class_state >= IFACE_INIT)
1496         type_iface_vtable_iface_init_Wm (iface, node);
1497     }
1498 
1499   /* create iface entries for children of this type */
1500   entry = type_lookup_iface_entry_L (node, iface);
1501   for (i = 0; i < node->n_children; i++)
1502     type_node_add_iface_entry_W (lookup_type_node_I (node->children[i]), NODE_TYPE (iface), entry);
1503 }
1504 
1505 static void
type_iface_add_prerequisite_W(TypeNode * iface,TypeNode * prerequisite_node)1506 type_iface_add_prerequisite_W (TypeNode *iface,
1507 			       TypeNode *prerequisite_node)
1508 {
1509   GType prerequisite_type = NODE_TYPE (prerequisite_node);
1510   GType *prerequisites, *dependants;
1511   guint n_dependants, i;
1512 
1513   g_assert (NODE_IS_IFACE (iface) &&
1514 	    IFACE_NODE_N_PREREQUISITES (iface) < MAX_N_PREREQUISITES &&
1515 	    (prerequisite_node->is_instantiatable || NODE_IS_IFACE (prerequisite_node)));
1516 
1517   prerequisites = IFACE_NODE_PREREQUISITES (iface);
1518   for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++)
1519     if (prerequisites[i] == prerequisite_type)
1520       return;			/* we already have that prerequisiste */
1521     else if (prerequisites[i] > prerequisite_type)
1522       break;
1523   IFACE_NODE_N_PREREQUISITES (iface) += 1;
1524   IFACE_NODE_PREREQUISITES (iface) = g_renew (GType,
1525 					      IFACE_NODE_PREREQUISITES (iface),
1526 					      IFACE_NODE_N_PREREQUISITES (iface));
1527   prerequisites = IFACE_NODE_PREREQUISITES (iface);
1528   memmove (prerequisites + i + 1, prerequisites + i,
1529            sizeof (prerequisites[0]) * (IFACE_NODE_N_PREREQUISITES (iface) - i - 1));
1530   prerequisites[i] = prerequisite_type;
1531 
1532   /* we want to get notified when prerequisites get added to prerequisite_node */
1533   if (NODE_IS_IFACE (prerequisite_node))
1534     {
1535       dependants = iface_node_get_dependants_array_L (prerequisite_node);
1536       n_dependants = dependants ? dependants[0] : 0;
1537       n_dependants += 1;
1538       dependants = g_renew (GType, dependants, n_dependants + 1);
1539       dependants[n_dependants] = NODE_TYPE (iface);
1540       dependants[0] = n_dependants;
1541       iface_node_set_dependants_array_W (prerequisite_node, dependants);
1542     }
1543 
1544   /* we need to notify all dependants */
1545   dependants = iface_node_get_dependants_array_L (iface);
1546   n_dependants = dependants ? dependants[0] : 0;
1547   for (i = 1; i <= n_dependants; i++)
1548     type_iface_add_prerequisite_W (lookup_type_node_I (dependants[i]), prerequisite_node);
1549 }
1550 
1551 /**
1552  * g_type_interface_add_prerequisite:
1553  * @interface_type: #GType value of an interface type
1554  * @prerequisite_type: #GType value of an interface or instantiatable type
1555  *
1556  * Adds @prerequisite_type to the list of prerequisites of @interface_type.
1557  * This means that any type implementing @interface_type must also implement
1558  * @prerequisite_type. Prerequisites can be thought of as an alternative to
1559  * interface derivation (which GType doesn't support). An interface can have
1560  * at most one instantiatable prerequisite type.
1561  */
1562 void
g_type_interface_add_prerequisite(GType interface_type,GType prerequisite_type)1563 g_type_interface_add_prerequisite (GType interface_type,
1564 				   GType prerequisite_type)
1565 {
1566   TypeNode *iface, *prerequisite_node;
1567   IFaceHolder *holders;
1568 
1569   g_return_if_fail (G_TYPE_IS_INTERFACE (interface_type));	/* G_TYPE_IS_INTERFACE() is an external call: _U */
1570   g_return_if_fail (!g_type_is_a (interface_type, prerequisite_type));
1571   g_return_if_fail (!g_type_is_a (prerequisite_type, interface_type));
1572 
1573   iface = lookup_type_node_I (interface_type);
1574   prerequisite_node = lookup_type_node_I (prerequisite_type);
1575   if (!iface || !prerequisite_node || !NODE_IS_IFACE (iface))
1576     {
1577       g_warning ("interface type '%s' or prerequisite type '%s' invalid",
1578 		 type_descriptive_name_I (interface_type),
1579 		 type_descriptive_name_I (prerequisite_type));
1580       return;
1581     }
1582   G_WRITE_LOCK (&type_rw_lock);
1583   holders = iface_node_get_holders_L (iface);
1584   if (holders)
1585     {
1586       G_WRITE_UNLOCK (&type_rw_lock);
1587       g_warning ("unable to add prerequisite '%s' to interface '%s' which is already in use for '%s'",
1588 		 type_descriptive_name_I (prerequisite_type),
1589 		 type_descriptive_name_I (interface_type),
1590 		 type_descriptive_name_I (holders->instance_type));
1591       return;
1592     }
1593   if (prerequisite_node->is_instantiatable)
1594     {
1595       guint i;
1596 
1597       /* can have at most one publicly installable instantiatable prerequisite */
1598       for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++)
1599 	{
1600 	  TypeNode *prnode = lookup_type_node_I (IFACE_NODE_PREREQUISITES (iface)[i]);
1601 
1602 	  if (prnode->is_instantiatable)
1603 	    {
1604 	      G_WRITE_UNLOCK (&type_rw_lock);
1605 	      g_warning ("adding prerequisite '%s' to interface '%s' conflicts with existing prerequisite '%s'",
1606 			 type_descriptive_name_I (prerequisite_type),
1607 			 type_descriptive_name_I (interface_type),
1608 			 type_descriptive_name_I (NODE_TYPE (prnode)));
1609 	      return;
1610 	    }
1611 	}
1612 
1613       for (i = 0; i < prerequisite_node->n_supers + 1u; i++)
1614 	type_iface_add_prerequisite_W (iface, lookup_type_node_I (prerequisite_node->supers[i]));
1615       G_WRITE_UNLOCK (&type_rw_lock);
1616     }
1617   else if (NODE_IS_IFACE (prerequisite_node))
1618     {
1619       GType *prerequisites;
1620       guint i;
1621 
1622       prerequisites = IFACE_NODE_PREREQUISITES (prerequisite_node);
1623       for (i = 0; i < IFACE_NODE_N_PREREQUISITES (prerequisite_node); i++)
1624 	type_iface_add_prerequisite_W (iface, lookup_type_node_I (prerequisites[i]));
1625       type_iface_add_prerequisite_W (iface, prerequisite_node);
1626       G_WRITE_UNLOCK (&type_rw_lock);
1627     }
1628   else
1629     {
1630       G_WRITE_UNLOCK (&type_rw_lock);
1631       g_warning ("prerequisite '%s' for interface '%s' is neither instantiatable nor interface",
1632 		 type_descriptive_name_I (prerequisite_type),
1633 		 type_descriptive_name_I (interface_type));
1634     }
1635 }
1636 
1637 /**
1638  * g_type_interface_prerequisites:
1639  * @interface_type: an interface type
1640  * @n_prerequisites: (out) (optional): location to return the number
1641  *     of prerequisites, or %NULL
1642  *
1643  * Returns the prerequisites of an interfaces type.
1644  *
1645  * Since: 2.2
1646  *
1647  * Returns: (array length=n_prerequisites) (transfer full): a
1648  *     newly-allocated zero-terminated array of #GType containing
1649  *     the prerequisites of @interface_type
1650  */
1651 GType*
g_type_interface_prerequisites(GType interface_type,guint * n_prerequisites)1652 g_type_interface_prerequisites (GType  interface_type,
1653 				guint *n_prerequisites)
1654 {
1655   TypeNode *iface;
1656 
1657   g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface_type), NULL);
1658 
1659   iface = lookup_type_node_I (interface_type);
1660   if (iface)
1661     {
1662       GType *types;
1663       TypeNode *inode = NULL;
1664       guint i, n = 0;
1665 
1666       G_READ_LOCK (&type_rw_lock);
1667       types = g_new0 (GType, IFACE_NODE_N_PREREQUISITES (iface) + 1);
1668       for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++)
1669 	{
1670 	  GType prerequisite = IFACE_NODE_PREREQUISITES (iface)[i];
1671 	  TypeNode *node = lookup_type_node_I (prerequisite);
1672 	  if (node->is_instantiatable)
1673             {
1674               if (!inode || type_node_is_a_L (node, inode))
1675 	        inode = node;
1676             }
1677 	  else
1678 	    types[n++] = NODE_TYPE (node);
1679 	}
1680       if (inode)
1681 	types[n++] = NODE_TYPE (inode);
1682 
1683       if (n_prerequisites)
1684 	*n_prerequisites = n;
1685       G_READ_UNLOCK (&type_rw_lock);
1686 
1687       return types;
1688     }
1689   else
1690     {
1691       if (n_prerequisites)
1692 	*n_prerequisites = 0;
1693 
1694       return NULL;
1695     }
1696 }
1697 
1698 /**
1699  * g_type_interface_instantiatable_prerequisite:
1700  * @interface_type: an interface type
1701  *
1702  * Returns the most specific instantiatable prerequisite of an
1703  * interface type. If the interface type has no instantiatable
1704  * prerequisite, %G_TYPE_INVALID is returned.
1705  *
1706  * See g_type_interface_add_prerequisite() for more information
1707  * about prerequisites.
1708  *
1709  * Returns: the instantiatable prerequisite type or %G_TYPE_INVALID if none
1710  *
1711  * Since: 2.68
1712  **/
1713 GType
g_type_interface_instantiatable_prerequisite(GType interface_type)1714 g_type_interface_instantiatable_prerequisite (GType interface_type)
1715 {
1716   TypeNode *inode = NULL;
1717   TypeNode *iface;
1718   guint i;
1719 
1720   g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface_type), G_TYPE_INVALID);
1721 
1722   iface = lookup_type_node_I (interface_type);
1723   if (iface == NULL)
1724     return G_TYPE_INVALID;
1725 
1726   G_READ_LOCK (&type_rw_lock);
1727 
1728   for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++)
1729     {
1730       GType prerequisite = IFACE_NODE_PREREQUISITES (iface)[i];
1731       TypeNode *node = lookup_type_node_I (prerequisite);
1732       if (node->is_instantiatable)
1733         {
1734           if (!inode || type_node_is_a_L (node, inode))
1735             inode = node;
1736         }
1737     }
1738 
1739   G_READ_UNLOCK (&type_rw_lock);
1740 
1741   if (inode)
1742     return NODE_TYPE (inode);
1743   else
1744     return G_TYPE_INVALID;
1745 }
1746 
1747 static IFaceHolder*
type_iface_peek_holder_L(TypeNode * iface,GType instance_type)1748 type_iface_peek_holder_L (TypeNode *iface,
1749 			  GType     instance_type)
1750 {
1751   IFaceHolder *iholder;
1752 
1753   g_assert (NODE_IS_IFACE (iface));
1754 
1755   iholder = iface_node_get_holders_L (iface);
1756   while (iholder && iholder->instance_type != instance_type)
1757     iholder = iholder->next;
1758   return iholder;
1759 }
1760 
1761 static IFaceHolder*
type_iface_retrieve_holder_info_Wm(TypeNode * iface,GType instance_type,gboolean need_info)1762 type_iface_retrieve_holder_info_Wm (TypeNode *iface,
1763 				    GType     instance_type,
1764 				    gboolean  need_info)
1765 {
1766   IFaceHolder *iholder = type_iface_peek_holder_L (iface, instance_type);
1767 
1768   if (iholder && !iholder->info && need_info)
1769     {
1770       GInterfaceInfo tmp_info;
1771 
1772       g_assert (iholder->plugin != NULL);
1773 
1774       type_data_ref_Wm (iface);
1775       if (iholder->info)
1776 	INVALID_RECURSION ("g_type_plugin_*", iface->plugin, NODE_NAME (iface));
1777 
1778       memset (&tmp_info, 0, sizeof (tmp_info));
1779 
1780       G_WRITE_UNLOCK (&type_rw_lock);
1781       g_type_plugin_use (iholder->plugin);
1782       g_type_plugin_complete_interface_info (iholder->plugin, instance_type, NODE_TYPE (iface), &tmp_info);
1783       G_WRITE_LOCK (&type_rw_lock);
1784       if (iholder->info)
1785         INVALID_RECURSION ("g_type_plugin_*", iholder->plugin, NODE_NAME (iface));
1786 
1787       check_interface_info_I (iface, instance_type, &tmp_info);
1788       iholder->info = g_memdup2 (&tmp_info, sizeof (tmp_info));
1789     }
1790 
1791   return iholder;	/* we don't modify write lock upon returning NULL */
1792 }
1793 
1794 static void
type_iface_blow_holder_info_Wm(TypeNode * iface,GType instance_type)1795 type_iface_blow_holder_info_Wm (TypeNode *iface,
1796 				GType     instance_type)
1797 {
1798   IFaceHolder *iholder = iface_node_get_holders_L (iface);
1799 
1800   g_assert (NODE_IS_IFACE (iface));
1801 
1802   while (iholder->instance_type != instance_type)
1803     iholder = iholder->next;
1804 
1805   if (iholder->info && iholder->plugin)
1806     {
1807       g_free (iholder->info);
1808       iholder->info = NULL;
1809 
1810       G_WRITE_UNLOCK (&type_rw_lock);
1811       g_type_plugin_unuse (iholder->plugin);
1812       type_data_unref_U (iface, FALSE);
1813       G_WRITE_LOCK (&type_rw_lock);
1814     }
1815 }
1816 
1817 /**
1818  * g_type_create_instance: (skip)
1819  * @type: an instantiatable type to create an instance for
1820  *
1821  * Creates and initializes an instance of @type if @type is valid and
1822  * can be instantiated. The type system only performs basic allocation
1823  * and structure setups for instances: actual instance creation should
1824  * happen through functions supplied by the type's fundamental type
1825  * implementation.  So use of g_type_create_instance() is reserved for
1826  * implementers of fundamental types only. E.g. instances of the
1827  * #GObject hierarchy should be created via g_object_new() and never
1828  * directly through g_type_create_instance() which doesn't handle things
1829  * like singleton objects or object construction.
1830  *
1831  * The extended members of the returned instance are guaranteed to be filled
1832  * with zeros.
1833  *
1834  * Note: Do not use this function, unless you're implementing a
1835  * fundamental type. Also language bindings should not use this
1836  * function, but g_object_new() instead.
1837  *
1838  * Returns: an allocated and initialized instance, subject to further
1839  *     treatment by the fundamental type implementation
1840  */
1841 GTypeInstance*
g_type_create_instance(GType type)1842 g_type_create_instance (GType type)
1843 {
1844   TypeNode *node;
1845   GTypeInstance *instance;
1846   GTypeClass *class;
1847   gchar *allocated;
1848   gint private_size;
1849   gint ivar_size;
1850   guint i;
1851 
1852   node = lookup_type_node_I (type);
1853   if (!node || !node->is_instantiatable)
1854     {
1855       g_error ("cannot create new instance of invalid (non-instantiatable) type '%s'",
1856 		 type_descriptive_name_I (type));
1857     }
1858   /* G_TYPE_IS_ABSTRACT() is an external call: _U */
1859   if (!node->mutatable_check_cache && G_TYPE_IS_ABSTRACT (type))
1860     {
1861       g_error ("cannot create instance of abstract (non-instantiatable) type '%s'",
1862 		 type_descriptive_name_I (type));
1863     }
1864 
1865   class = g_type_class_ref (type);
1866 
1867   /* We allocate the 'private' areas before the normal instance data, in
1868    * reverse order.  This allows the private area of a particular class
1869    * to always be at a constant relative address to the instance data.
1870    * If we stored the private data after the instance data this would
1871    * not be the case (since a subclass that added more instance
1872    * variables would push the private data further along).
1873    *
1874    * This presents problems for valgrindability, of course, so we do a
1875    * workaround for that case.  We identify the start of the object to
1876    * valgrind as an allocated block (so that pointers to objects show up
1877    * as 'reachable' instead of 'possibly lost').  We then add an extra
1878    * pointer at the end of the object, after all instance data, back to
1879    * the start of the private area so that it is also recorded as
1880    * reachable.  We also add extra private space at the start because
1881    * valgrind doesn't seem to like us claiming to have allocated an
1882    * address that it saw allocated by malloc().
1883    */
1884   private_size = node->data->instance.private_size;
1885   ivar_size = node->data->instance.instance_size;
1886 
1887 #ifdef ENABLE_VALGRIND
1888   if (private_size && RUNNING_ON_VALGRIND)
1889     {
1890       private_size += ALIGN_STRUCT (1);
1891 
1892       /* Allocate one extra pointer size... */
1893       allocated = g_slice_alloc0 (private_size + ivar_size + sizeof (gpointer));
1894       /* ... and point it back to the start of the private data. */
1895       *(gpointer *) (allocated + private_size + ivar_size) = allocated + ALIGN_STRUCT (1);
1896 
1897       /* Tell valgrind that it should treat the object itself as such */
1898       VALGRIND_MALLOCLIKE_BLOCK (allocated + private_size, ivar_size + sizeof (gpointer), 0, TRUE);
1899       VALGRIND_MALLOCLIKE_BLOCK (allocated + ALIGN_STRUCT (1), private_size - ALIGN_STRUCT (1), 0, TRUE);
1900     }
1901   else
1902 #endif
1903     allocated = g_slice_alloc0 (private_size + ivar_size);
1904 
1905   instance = (GTypeInstance *) (allocated + private_size);
1906 
1907   for (i = node->n_supers; i > 0; i--)
1908     {
1909       TypeNode *pnode;
1910 
1911       pnode = lookup_type_node_I (node->supers[i]);
1912       if (pnode->data->instance.instance_init)
1913 	{
1914 	  instance->g_class = pnode->data->instance.class;
1915 	  pnode->data->instance.instance_init (instance, class);
1916 	}
1917     }
1918 
1919   instance->g_class = class;
1920   if (node->data->instance.instance_init)
1921     node->data->instance.instance_init (instance, class);
1922 
1923 #ifdef	G_ENABLE_DEBUG
1924   IF_DEBUG (INSTANCE_COUNT)
1925     {
1926       g_atomic_int_inc ((int *) &node->instance_count);
1927     }
1928 #endif
1929 
1930   TRACE(GOBJECT_OBJECT_NEW(instance, type));
1931 
1932   return instance;
1933 }
1934 
1935 /**
1936  * g_type_free_instance:
1937  * @instance: an instance of a type
1938  *
1939  * Frees an instance of a type, returning it to the instance pool for
1940  * the type, if there is one.
1941  *
1942  * Like g_type_create_instance(), this function is reserved for
1943  * implementors of fundamental types.
1944  */
1945 void
g_type_free_instance(GTypeInstance * instance)1946 g_type_free_instance (GTypeInstance *instance)
1947 {
1948   TypeNode *node;
1949   GTypeClass *class;
1950   gchar *allocated;
1951   gint private_size;
1952   gint ivar_size;
1953 
1954   g_return_if_fail (instance != NULL && instance->g_class != NULL);
1955 
1956   class = instance->g_class;
1957   node = lookup_type_node_I (class->g_type);
1958   if (!node || !node->is_instantiatable || !node->data || node->data->class.class != (gpointer) class)
1959     {
1960       g_warning ("cannot free instance of invalid (non-instantiatable) type '%s'",
1961 		 type_descriptive_name_I (class->g_type));
1962       return;
1963     }
1964   /* G_TYPE_IS_ABSTRACT() is an external call: _U */
1965   if (!node->mutatable_check_cache && G_TYPE_IS_ABSTRACT (NODE_TYPE (node)))
1966     {
1967       g_warning ("cannot free instance of abstract (non-instantiatable) type '%s'",
1968 		 NODE_NAME (node));
1969       return;
1970     }
1971 
1972   instance->g_class = NULL;
1973   private_size = node->data->instance.private_size;
1974   ivar_size = node->data->instance.instance_size;
1975   allocated = ((gchar *) instance) - private_size;
1976 
1977 #ifdef G_ENABLE_DEBUG
1978   memset (allocated, 0xaa, ivar_size + private_size);
1979 #endif
1980 
1981 #ifdef ENABLE_VALGRIND
1982   /* See comment in g_type_create_instance() about what's going on here.
1983    * We're basically unwinding what we put into motion there.
1984    */
1985   if (private_size && RUNNING_ON_VALGRIND)
1986     {
1987       private_size += ALIGN_STRUCT (1);
1988       allocated -= ALIGN_STRUCT (1);
1989 
1990       /* Clear out the extra pointer... */
1991       *(gpointer *) (allocated + private_size + ivar_size) = NULL;
1992       /* ... and ensure we include it in the size we free. */
1993       g_slice_free1 (private_size + ivar_size + sizeof (gpointer), allocated);
1994 
1995       VALGRIND_FREELIKE_BLOCK (allocated + ALIGN_STRUCT (1), 0);
1996       VALGRIND_FREELIKE_BLOCK (instance, 0);
1997     }
1998   else
1999 #endif
2000     g_slice_free1 (private_size + ivar_size, allocated);
2001 
2002 #ifdef	G_ENABLE_DEBUG
2003   IF_DEBUG (INSTANCE_COUNT)
2004     {
2005       g_atomic_int_add ((int *) &node->instance_count, -1);
2006     }
2007 #endif
2008 
2009   g_type_class_unref (class);
2010 }
2011 
2012 static void
type_iface_ensure_dflt_vtable_Wm(TypeNode * iface)2013 type_iface_ensure_dflt_vtable_Wm (TypeNode *iface)
2014 {
2015   g_assert (iface->data);
2016 
2017   if (!iface->data->iface.dflt_vtable)
2018     {
2019       GTypeInterface *vtable = g_malloc0 (iface->data->iface.vtable_size);
2020       iface->data->iface.dflt_vtable = vtable;
2021       vtable->g_type = NODE_TYPE (iface);
2022       vtable->g_instance_type = 0;
2023       if (iface->data->iface.vtable_init_base ||
2024           iface->data->iface.dflt_init)
2025         {
2026           G_WRITE_UNLOCK (&type_rw_lock);
2027           if (iface->data->iface.vtable_init_base)
2028             iface->data->iface.vtable_init_base (vtable);
2029           if (iface->data->iface.dflt_init)
2030             iface->data->iface.dflt_init (vtable, (gpointer) iface->data->iface.dflt_data);
2031           G_WRITE_LOCK (&type_rw_lock);
2032         }
2033     }
2034 }
2035 
2036 
2037 /* This is called to allocate and do the first part of initializing
2038  * the interface vtable; type_iface_vtable_iface_init_Wm() does the remainder.
2039  *
2040  * A FALSE return indicates that we didn't find an init function for
2041  * this type/iface pair, so the vtable from the parent type should
2042  * be used. Note that the write lock is not modified upon a FALSE
2043  * return.
2044  */
2045 static gboolean
type_iface_vtable_base_init_Wm(TypeNode * iface,TypeNode * node)2046 type_iface_vtable_base_init_Wm (TypeNode *iface,
2047 				TypeNode *node)
2048 {
2049   IFaceEntry *entry;
2050   IFaceHolder *iholder;
2051   GTypeInterface *vtable = NULL;
2052   TypeNode *pnode;
2053 
2054   /* type_iface_retrieve_holder_info_Wm() doesn't modify write lock for returning NULL */
2055   iholder = type_iface_retrieve_holder_info_Wm (iface, NODE_TYPE (node), TRUE);
2056   if (!iholder)
2057     return FALSE;	/* we don't modify write lock upon FALSE */
2058 
2059   type_iface_ensure_dflt_vtable_Wm (iface);
2060 
2061   entry = type_lookup_iface_entry_L (node, iface);
2062 
2063   g_assert (iface->data && entry && entry->vtable == NULL && iholder && iholder->info);
2064 
2065   entry->init_state = IFACE_INIT;
2066 
2067   pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
2068   if (pnode)	/* want to copy over parent iface contents */
2069     {
2070       IFaceEntry *pentry = type_lookup_iface_entry_L (pnode, iface);
2071 
2072       if (pentry)
2073 	vtable = g_memdup2 (pentry->vtable, iface->data->iface.vtable_size);
2074     }
2075   if (!vtable)
2076     vtable = g_memdup2 (iface->data->iface.dflt_vtable, iface->data->iface.vtable_size);
2077   entry->vtable = vtable;
2078   vtable->g_type = NODE_TYPE (iface);
2079   vtable->g_instance_type = NODE_TYPE (node);
2080 
2081   if (iface->data->iface.vtable_init_base)
2082     {
2083       G_WRITE_UNLOCK (&type_rw_lock);
2084       iface->data->iface.vtable_init_base (vtable);
2085       G_WRITE_LOCK (&type_rw_lock);
2086     }
2087   return TRUE;	/* initialized the vtable */
2088 }
2089 
2090 /* Finishes what type_iface_vtable_base_init_Wm started by
2091  * calling the interface init function.
2092  * this function may only be called for types with their
2093  * own interface holder info, i.e. types for which
2094  * g_type_add_interface*() was called and not children thereof.
2095  */
2096 static void
type_iface_vtable_iface_init_Wm(TypeNode * iface,TypeNode * node)2097 type_iface_vtable_iface_init_Wm (TypeNode *iface,
2098 				 TypeNode *node)
2099 {
2100   IFaceEntry *entry = type_lookup_iface_entry_L (node, iface);
2101   IFaceHolder *iholder = type_iface_peek_holder_L (iface, NODE_TYPE (node));
2102   GTypeInterface *vtable = NULL;
2103   guint i;
2104 
2105   /* iholder->info should have been filled in by type_iface_vtable_base_init_Wm() */
2106   g_assert (iface->data && entry && iholder && iholder->info);
2107   g_assert (entry->init_state == IFACE_INIT); /* assert prior base_init() */
2108 
2109   entry->init_state = INITIALIZED;
2110 
2111   vtable = entry->vtable;
2112 
2113   if (iholder->info->interface_init)
2114     {
2115       G_WRITE_UNLOCK (&type_rw_lock);
2116       if (iholder->info->interface_init)
2117 	iholder->info->interface_init (vtable, iholder->info->interface_data);
2118       G_WRITE_LOCK (&type_rw_lock);
2119     }
2120 
2121   for (i = 0; i < static_n_iface_check_funcs; i++)
2122     {
2123       GTypeInterfaceCheckFunc check_func = static_iface_check_funcs[i].check_func;
2124       gpointer check_data = static_iface_check_funcs[i].check_data;
2125 
2126       G_WRITE_UNLOCK (&type_rw_lock);
2127       check_func (check_data, (gpointer)vtable);
2128       G_WRITE_LOCK (&type_rw_lock);
2129     }
2130 }
2131 
2132 static gboolean
type_iface_vtable_finalize_Wm(TypeNode * iface,TypeNode * node,GTypeInterface * vtable)2133 type_iface_vtable_finalize_Wm (TypeNode       *iface,
2134 			       TypeNode       *node,
2135 			       GTypeInterface *vtable)
2136 {
2137   IFaceEntry *entry = type_lookup_iface_entry_L (node, iface);
2138   IFaceHolder *iholder;
2139 
2140   /* type_iface_retrieve_holder_info_Wm() doesn't modify write lock for returning NULL */
2141   iholder = type_iface_retrieve_holder_info_Wm (iface, NODE_TYPE (node), FALSE);
2142   if (!iholder)
2143     return FALSE;	/* we don't modify write lock upon FALSE */
2144 
2145   g_assert (entry && entry->vtable == vtable && iholder->info);
2146 
2147   entry->vtable = NULL;
2148   entry->init_state = UNINITIALIZED;
2149   if (iholder->info->interface_finalize || iface->data->iface.vtable_finalize_base)
2150     {
2151       G_WRITE_UNLOCK (&type_rw_lock);
2152       if (iholder->info->interface_finalize)
2153 	iholder->info->interface_finalize (vtable, iholder->info->interface_data);
2154       if (iface->data->iface.vtable_finalize_base)
2155 	iface->data->iface.vtable_finalize_base (vtable);
2156       G_WRITE_LOCK (&type_rw_lock);
2157     }
2158   vtable->g_type = 0;
2159   vtable->g_instance_type = 0;
2160   g_free (vtable);
2161 
2162   type_iface_blow_holder_info_Wm (iface, NODE_TYPE (node));
2163 
2164   return TRUE;	/* write lock modified */
2165 }
2166 
2167 static void
type_class_init_Wm(TypeNode * node,GTypeClass * pclass)2168 type_class_init_Wm (TypeNode   *node,
2169 		    GTypeClass *pclass)
2170 {
2171   GSList *slist, *init_slist = NULL;
2172   GTypeClass *class;
2173   IFaceEntries *entries;
2174   IFaceEntry *entry;
2175   TypeNode *bnode, *pnode;
2176   guint i;
2177 
2178   /* Accessing data->class will work for instantiatable types
2179    * too because ClassData is a subset of InstanceData
2180    */
2181   g_assert (node->is_classed && node->data &&
2182 	    node->data->class.class_size &&
2183 	    !node->data->class.class &&
2184 	    g_atomic_int_get (&node->data->class.init_state) == UNINITIALIZED);
2185   if (node->data->class.class_private_size)
2186     class = g_malloc0 (ALIGN_STRUCT (node->data->class.class_size) + node->data->class.class_private_size);
2187   else
2188     class = g_malloc0 (node->data->class.class_size);
2189   node->data->class.class = class;
2190   g_atomic_int_set (&node->data->class.init_state, BASE_CLASS_INIT);
2191 
2192   if (pclass)
2193     {
2194       TypeNode *pnode = lookup_type_node_I (pclass->g_type);
2195 
2196       memcpy (class, pclass, pnode->data->class.class_size);
2197       memcpy (G_STRUCT_MEMBER_P (class, ALIGN_STRUCT (node->data->class.class_size)), G_STRUCT_MEMBER_P (pclass, ALIGN_STRUCT (pnode->data->class.class_size)), pnode->data->class.class_private_size);
2198 
2199       if (node->is_instantiatable)
2200 	{
2201 	  /* We need to initialize the private_size here rather than in
2202 	   * type_data_make_W() since the class init for the parent
2203 	   * class may have changed pnode->data->instance.private_size.
2204 	   */
2205 	  node->data->instance.private_size = pnode->data->instance.private_size;
2206 	}
2207     }
2208   class->g_type = NODE_TYPE (node);
2209 
2210   G_WRITE_UNLOCK (&type_rw_lock);
2211 
2212   /* stack all base class initialization functions, so we
2213    * call them in ascending order.
2214    */
2215   for (bnode = node; bnode; bnode = lookup_type_node_I (NODE_PARENT_TYPE (bnode)))
2216     if (bnode->data->class.class_init_base)
2217       init_slist = g_slist_prepend (init_slist, (gpointer) bnode->data->class.class_init_base);
2218   for (slist = init_slist; slist; slist = slist->next)
2219     {
2220       GBaseInitFunc class_init_base = (GBaseInitFunc) slist->data;
2221 
2222       class_init_base (class);
2223     }
2224   g_slist_free (init_slist);
2225 
2226   G_WRITE_LOCK (&type_rw_lock);
2227 
2228   g_atomic_int_set (&node->data->class.init_state, BASE_IFACE_INIT);
2229 
2230   /* Before we initialize the class, base initialize all interfaces, either
2231    * from parent, or through our holder info
2232    */
2233   pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
2234 
2235   i = 0;
2236   while ((entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node)) != NULL &&
2237 	  i < IFACE_ENTRIES_N_ENTRIES (entries))
2238     {
2239       entry = &entries->entry[i];
2240       while (i < IFACE_ENTRIES_N_ENTRIES (entries) &&
2241 	     entry->init_state == IFACE_INIT)
2242 	{
2243 	  entry++;
2244 	  i++;
2245 	}
2246 
2247       if (i == IFACE_ENTRIES_N_ENTRIES (entries))
2248 	break;
2249 
2250       if (!type_iface_vtable_base_init_Wm (lookup_type_node_I (entry->iface_type), node))
2251 	{
2252 	  guint j;
2253 	  IFaceEntries *pentries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (pnode);
2254 
2255 	  /* need to get this interface from parent, type_iface_vtable_base_init_Wm()
2256 	   * doesn't modify write lock upon FALSE, so entry is still valid;
2257 	   */
2258 	  g_assert (pnode != NULL);
2259 
2260 	  if (pentries)
2261 	    for (j = 0; j < IFACE_ENTRIES_N_ENTRIES (pentries); j++)
2262 	      {
2263 		IFaceEntry *pentry = &pentries->entry[j];
2264 
2265 		if (pentry->iface_type == entry->iface_type)
2266 		  {
2267 		    entry->vtable = pentry->vtable;
2268 		    entry->init_state = INITIALIZED;
2269 		    break;
2270 		  }
2271 	      }
2272 	  g_assert (entry->vtable != NULL);
2273 	}
2274 
2275       /* If the write lock was released, additional interface entries might
2276        * have been inserted into CLASSED_NODE_IFACES_ENTRIES (node); they'll
2277        * be base-initialized when inserted, so we don't have to worry that
2278        * we might miss them. Uninitialized entries can only be moved higher
2279        * when new ones are inserted.
2280        */
2281       i++;
2282     }
2283 
2284   g_atomic_int_set (&node->data->class.init_state, CLASS_INIT);
2285 
2286   G_WRITE_UNLOCK (&type_rw_lock);
2287 
2288   if (node->data->class.class_init)
2289     node->data->class.class_init (class, (gpointer) node->data->class.class_data);
2290 
2291   G_WRITE_LOCK (&type_rw_lock);
2292 
2293   g_atomic_int_set (&node->data->class.init_state, IFACE_INIT);
2294 
2295   /* finish initializing the interfaces through our holder info.
2296    * inherited interfaces are already init_state == INITIALIZED, because
2297    * they either got setup in the above base_init loop, or during
2298    * class_init from within type_add_interface_Wm() for this or
2299    * an ancestor type.
2300    */
2301   i = 0;
2302   while ((entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node)) != NULL)
2303     {
2304       entry = &entries->entry[i];
2305       while (i < IFACE_ENTRIES_N_ENTRIES (entries) &&
2306 	     entry->init_state == INITIALIZED)
2307 	{
2308 	  entry++;
2309 	  i++;
2310 	}
2311 
2312       if (i == IFACE_ENTRIES_N_ENTRIES (entries))
2313 	break;
2314 
2315       type_iface_vtable_iface_init_Wm (lookup_type_node_I (entry->iface_type), node);
2316 
2317       /* As in the loop above, additional initialized entries might be inserted
2318        * if the write lock is released, but that's harmless because the entries
2319        * we need to initialize only move higher in the list.
2320        */
2321       i++;
2322     }
2323 
2324   g_atomic_int_set (&node->data->class.init_state, INITIALIZED);
2325 }
2326 
2327 static void
type_data_finalize_class_ifaces_Wm(TypeNode * node)2328 type_data_finalize_class_ifaces_Wm (TypeNode *node)
2329 {
2330   guint i;
2331   IFaceEntries *entries;
2332 
2333   g_assert (node->is_instantiatable && node->data && node->data->class.class && NODE_REFCOUNT (node) == 0);
2334 
2335  reiterate:
2336   entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node);
2337   for (i = 0; entries != NULL && i < IFACE_ENTRIES_N_ENTRIES (entries); i++)
2338     {
2339       IFaceEntry *entry = &entries->entry[i];
2340       if (entry->vtable)
2341 	{
2342           if (type_iface_vtable_finalize_Wm (lookup_type_node_I (entry->iface_type), node, entry->vtable))
2343             {
2344               /* refetch entries, IFACES_ENTRIES might be modified */
2345               goto reiterate;
2346             }
2347           else
2348             {
2349               /* type_iface_vtable_finalize_Wm() doesn't modify write lock upon FALSE,
2350                * iface vtable came from parent
2351                */
2352               entry->vtable = NULL;
2353               entry->init_state = UNINITIALIZED;
2354             }
2355 	}
2356     }
2357 }
2358 
2359 static void
type_data_finalize_class_U(TypeNode * node,ClassData * cdata)2360 type_data_finalize_class_U (TypeNode  *node,
2361 			    ClassData *cdata)
2362 {
2363   GTypeClass *class = cdata->class;
2364   TypeNode *bnode;
2365 
2366   g_assert (cdata->class && NODE_REFCOUNT (node) == 0);
2367 
2368   if (cdata->class_finalize)
2369     cdata->class_finalize (class, (gpointer) cdata->class_data);
2370 
2371   /* call all base class destruction functions in descending order
2372    */
2373   if (cdata->class_finalize_base)
2374     cdata->class_finalize_base (class);
2375   for (bnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); bnode; bnode = lookup_type_node_I (NODE_PARENT_TYPE (bnode)))
2376     if (bnode->data->class.class_finalize_base)
2377       bnode->data->class.class_finalize_base (class);
2378 
2379   g_free (cdata->class);
2380 }
2381 
2382 static void
type_data_last_unref_Wm(TypeNode * node,gboolean uncached)2383 type_data_last_unref_Wm (TypeNode *node,
2384 			 gboolean  uncached)
2385 {
2386   g_return_if_fail (node != NULL && node->plugin != NULL);
2387 
2388   if (!node->data || NODE_REFCOUNT (node) == 0)
2389     {
2390       g_warning ("cannot drop last reference to unreferenced type '%s'",
2391 		 NODE_NAME (node));
2392       return;
2393     }
2394 
2395   /* call class cache hooks */
2396   if (node->is_classed && node->data && node->data->class.class && static_n_class_cache_funcs && !uncached)
2397     {
2398       guint i;
2399 
2400       G_WRITE_UNLOCK (&type_rw_lock);
2401       G_READ_LOCK (&type_rw_lock);
2402       for (i = 0; i < static_n_class_cache_funcs; i++)
2403 	{
2404 	  GTypeClassCacheFunc cache_func = static_class_cache_funcs[i].cache_func;
2405 	  gpointer cache_data = static_class_cache_funcs[i].cache_data;
2406 	  gboolean need_break;
2407 
2408 	  G_READ_UNLOCK (&type_rw_lock);
2409 	  need_break = cache_func (cache_data, node->data->class.class);
2410 	  G_READ_LOCK (&type_rw_lock);
2411 	  if (!node->data || NODE_REFCOUNT (node) == 0)
2412 	    INVALID_RECURSION ("GType class cache function ", cache_func, NODE_NAME (node));
2413 	  if (need_break)
2414 	    break;
2415 	}
2416       G_READ_UNLOCK (&type_rw_lock);
2417       G_WRITE_LOCK (&type_rw_lock);
2418     }
2419 
2420   /* may have been re-referenced meanwhile */
2421   if (g_atomic_int_dec_and_test ((int *) &node->ref_count))
2422     {
2423       GType ptype = NODE_PARENT_TYPE (node);
2424       TypeData *tdata;
2425 
2426       if (node->is_instantiatable)
2427 	{
2428 	  /* destroy node->data->instance.mem_chunk */
2429 	}
2430 
2431       tdata = node->data;
2432       if (node->is_classed && tdata->class.class)
2433 	{
2434 	  if (CLASSED_NODE_IFACES_ENTRIES_LOCKED (node) != NULL)
2435 	    type_data_finalize_class_ifaces_Wm (node);
2436 	  node->mutatable_check_cache = FALSE;
2437 	  node->data = NULL;
2438 	  G_WRITE_UNLOCK (&type_rw_lock);
2439 	  type_data_finalize_class_U (node, &tdata->class);
2440 	  G_WRITE_LOCK (&type_rw_lock);
2441 	}
2442       else if (NODE_IS_IFACE (node) && tdata->iface.dflt_vtable)
2443         {
2444           node->mutatable_check_cache = FALSE;
2445           node->data = NULL;
2446           if (tdata->iface.dflt_finalize || tdata->iface.vtable_finalize_base)
2447             {
2448               G_WRITE_UNLOCK (&type_rw_lock);
2449               if (tdata->iface.dflt_finalize)
2450                 tdata->iface.dflt_finalize (tdata->iface.dflt_vtable, (gpointer) tdata->iface.dflt_data);
2451               if (tdata->iface.vtable_finalize_base)
2452                 tdata->iface.vtable_finalize_base (tdata->iface.dflt_vtable);
2453               G_WRITE_LOCK (&type_rw_lock);
2454             }
2455           g_free (tdata->iface.dflt_vtable);
2456         }
2457       else
2458         {
2459           node->mutatable_check_cache = FALSE;
2460           node->data = NULL;
2461         }
2462 
2463       /* freeing tdata->common.value_table and its contents is taken care of
2464        * by allocating it in one chunk with tdata
2465        */
2466       g_free (tdata);
2467 
2468       G_WRITE_UNLOCK (&type_rw_lock);
2469       g_type_plugin_unuse (node->plugin);
2470       if (ptype)
2471 	type_data_unref_U (lookup_type_node_I (ptype), FALSE);
2472       G_WRITE_LOCK (&type_rw_lock);
2473     }
2474 }
2475 
2476 static inline void
type_data_unref_U(TypeNode * node,gboolean uncached)2477 type_data_unref_U (TypeNode *node,
2478                    gboolean  uncached)
2479 {
2480   guint current;
2481 
2482   do {
2483     current = NODE_REFCOUNT (node);
2484 
2485     if (current <= 1)
2486     {
2487       if (!node->plugin)
2488 	{
2489 	  g_warning ("static type '%s' unreferenced too often",
2490 		     NODE_NAME (node));
2491 	  return;
2492 	}
2493       else
2494         {
2495           /* This is the last reference of a type from a plugin.  We are
2496            * experimentally disabling support for unloading type
2497            * plugins, so don't allow the last ref to drop.
2498            */
2499           return;
2500         }
2501 
2502       g_assert (current > 0);
2503 
2504       g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */
2505       G_WRITE_LOCK (&type_rw_lock);
2506       type_data_last_unref_Wm (node, uncached);
2507       G_WRITE_UNLOCK (&type_rw_lock);
2508       g_rec_mutex_unlock (&class_init_rec_mutex);
2509       return;
2510     }
2511   } while (!g_atomic_int_compare_and_exchange ((int *) &node->ref_count, current, current - 1));
2512 }
2513 
2514 /**
2515  * g_type_add_class_cache_func: (skip)
2516  * @cache_data: data to be passed to @cache_func
2517  * @cache_func: a #GTypeClassCacheFunc
2518  *
2519  * Adds a #GTypeClassCacheFunc to be called before the reference count of a
2520  * class goes from one to zero. This can be used to prevent premature class
2521  * destruction. All installed #GTypeClassCacheFunc functions will be chained
2522  * until one of them returns %TRUE. The functions have to check the class id
2523  * passed in to figure whether they actually want to cache the class of this
2524  * type, since all classes are routed through the same #GTypeClassCacheFunc
2525  * chain.
2526  */
2527 void
g_type_add_class_cache_func(gpointer cache_data,GTypeClassCacheFunc cache_func)2528 g_type_add_class_cache_func (gpointer            cache_data,
2529 			     GTypeClassCacheFunc cache_func)
2530 {
2531   guint i;
2532 
2533   g_return_if_fail (cache_func != NULL);
2534 
2535   G_WRITE_LOCK (&type_rw_lock);
2536   i = static_n_class_cache_funcs++;
2537   static_class_cache_funcs = g_renew (ClassCacheFunc, static_class_cache_funcs, static_n_class_cache_funcs);
2538   static_class_cache_funcs[i].cache_data = cache_data;
2539   static_class_cache_funcs[i].cache_func = cache_func;
2540   G_WRITE_UNLOCK (&type_rw_lock);
2541 }
2542 
2543 /**
2544  * g_type_remove_class_cache_func: (skip)
2545  * @cache_data: data that was given when adding @cache_func
2546  * @cache_func: a #GTypeClassCacheFunc
2547  *
2548  * Removes a previously installed #GTypeClassCacheFunc. The cache
2549  * maintained by @cache_func has to be empty when calling
2550  * g_type_remove_class_cache_func() to avoid leaks.
2551  */
2552 void
g_type_remove_class_cache_func(gpointer cache_data,GTypeClassCacheFunc cache_func)2553 g_type_remove_class_cache_func (gpointer            cache_data,
2554 				GTypeClassCacheFunc cache_func)
2555 {
2556   gboolean found_it = FALSE;
2557   guint i;
2558 
2559   g_return_if_fail (cache_func != NULL);
2560 
2561   G_WRITE_LOCK (&type_rw_lock);
2562   for (i = 0; i < static_n_class_cache_funcs; i++)
2563     if (static_class_cache_funcs[i].cache_data == cache_data &&
2564 	static_class_cache_funcs[i].cache_func == cache_func)
2565       {
2566 	static_n_class_cache_funcs--;
2567 	memmove (static_class_cache_funcs + i,
2568                  static_class_cache_funcs + i + 1,
2569                  sizeof (static_class_cache_funcs[0]) * (static_n_class_cache_funcs - i));
2570 	static_class_cache_funcs = g_renew (ClassCacheFunc, static_class_cache_funcs, static_n_class_cache_funcs);
2571 	found_it = TRUE;
2572 	break;
2573       }
2574   G_WRITE_UNLOCK (&type_rw_lock);
2575 
2576   if (!found_it)
2577     g_warning (G_STRLOC ": cannot remove unregistered class cache func %p with data %p",
2578 	       cache_func, cache_data);
2579 }
2580 
2581 
2582 /**
2583  * g_type_add_interface_check: (skip)
2584  * @check_data: data to pass to @check_func
2585  * @check_func: function to be called after each interface
2586  *     is initialized
2587  *
2588  * Adds a function to be called after an interface vtable is
2589  * initialized for any class (i.e. after the @interface_init
2590  * member of #GInterfaceInfo has been called).
2591  *
2592  * This function is useful when you want to check an invariant
2593  * that depends on the interfaces of a class. For instance, the
2594  * implementation of #GObject uses this facility to check that an
2595  * object implements all of the properties that are defined on its
2596  * interfaces.
2597  *
2598  * Since: 2.4
2599  */
2600 void
g_type_add_interface_check(gpointer check_data,GTypeInterfaceCheckFunc check_func)2601 g_type_add_interface_check (gpointer	            check_data,
2602 			    GTypeInterfaceCheckFunc check_func)
2603 {
2604   guint i;
2605 
2606   g_return_if_fail (check_func != NULL);
2607 
2608   G_WRITE_LOCK (&type_rw_lock);
2609   i = static_n_iface_check_funcs++;
2610   static_iface_check_funcs = g_renew (IFaceCheckFunc, static_iface_check_funcs, static_n_iface_check_funcs);
2611   static_iface_check_funcs[i].check_data = check_data;
2612   static_iface_check_funcs[i].check_func = check_func;
2613   G_WRITE_UNLOCK (&type_rw_lock);
2614 }
2615 
2616 /**
2617  * g_type_remove_interface_check: (skip)
2618  * @check_data: callback data passed to g_type_add_interface_check()
2619  * @check_func: callback function passed to g_type_add_interface_check()
2620  *
2621  * Removes an interface check function added with
2622  * g_type_add_interface_check().
2623  *
2624  * Since: 2.4
2625  */
2626 void
g_type_remove_interface_check(gpointer check_data,GTypeInterfaceCheckFunc check_func)2627 g_type_remove_interface_check (gpointer                check_data,
2628 			       GTypeInterfaceCheckFunc check_func)
2629 {
2630   gboolean found_it = FALSE;
2631   guint i;
2632 
2633   g_return_if_fail (check_func != NULL);
2634 
2635   G_WRITE_LOCK (&type_rw_lock);
2636   for (i = 0; i < static_n_iface_check_funcs; i++)
2637     if (static_iface_check_funcs[i].check_data == check_data &&
2638 	static_iface_check_funcs[i].check_func == check_func)
2639       {
2640 	static_n_iface_check_funcs--;
2641 	memmove (static_iface_check_funcs + i,
2642                  static_iface_check_funcs + i + 1,
2643                  sizeof (static_iface_check_funcs[0]) * (static_n_iface_check_funcs - i));
2644 	static_iface_check_funcs = g_renew (IFaceCheckFunc, static_iface_check_funcs, static_n_iface_check_funcs);
2645 	found_it = TRUE;
2646 	break;
2647       }
2648   G_WRITE_UNLOCK (&type_rw_lock);
2649 
2650   if (!found_it)
2651     g_warning (G_STRLOC ": cannot remove unregistered class check func %p with data %p",
2652 	       check_func, check_data);
2653 }
2654 
2655 /* --- type registration --- */
2656 /**
2657  * g_type_register_fundamental:
2658  * @type_id: a predefined type identifier
2659  * @type_name: 0-terminated string used as the name of the new type
2660  * @info: #GTypeInfo structure for this type
2661  * @finfo: #GTypeFundamentalInfo structure for this type
2662  * @flags: bitwise combination of #GTypeFlags values
2663  *
2664  * Registers @type_id as the predefined identifier and @type_name as the
2665  * name of a fundamental type. If @type_id is already registered, or a
2666  * type named @type_name is already registered, the behaviour is undefined.
2667  * The type system uses the information contained in the #GTypeInfo structure
2668  * pointed to by @info and the #GTypeFundamentalInfo structure pointed to by
2669  * @finfo to manage the type and its instances. The value of @flags determines
2670  * additional characteristics of the fundamental type.
2671  *
2672  * Returns: the predefined type identifier
2673  */
2674 GType
g_type_register_fundamental(GType type_id,const gchar * type_name,const GTypeInfo * info,const GTypeFundamentalInfo * finfo,GTypeFlags flags)2675 g_type_register_fundamental (GType                       type_id,
2676 			     const gchar                *type_name,
2677 			     const GTypeInfo            *info,
2678 			     const GTypeFundamentalInfo *finfo,
2679 			     GTypeFlags			 flags)
2680 {
2681   TypeNode *node;
2682 
2683   g_assert_type_system_initialized ();
2684   g_return_val_if_fail (type_id > 0, 0);
2685   g_return_val_if_fail (type_name != NULL, 0);
2686   g_return_val_if_fail (info != NULL, 0);
2687   g_return_val_if_fail (finfo != NULL, 0);
2688 
2689   if (!check_type_name_I (type_name))
2690     return 0;
2691   if ((type_id & TYPE_ID_MASK) ||
2692       type_id > G_TYPE_FUNDAMENTAL_MAX)
2693     {
2694       g_warning ("attempt to register fundamental type '%s' with invalid type id (%" G_GSIZE_FORMAT ")",
2695 		 type_name,
2696 		 type_id);
2697       return 0;
2698     }
2699   if ((finfo->type_flags & G_TYPE_FLAG_INSTANTIATABLE) &&
2700       !(finfo->type_flags & G_TYPE_FLAG_CLASSED))
2701     {
2702       g_warning ("cannot register instantiatable fundamental type '%s' as non-classed",
2703 		 type_name);
2704       return 0;
2705     }
2706   if (lookup_type_node_I (type_id))
2707     {
2708       g_warning ("cannot register existing fundamental type '%s' (as '%s')",
2709 		 type_descriptive_name_I (type_id),
2710 		 type_name);
2711       return 0;
2712     }
2713 
2714   G_WRITE_LOCK (&type_rw_lock);
2715   node = type_node_fundamental_new_W (type_id, type_name, finfo->type_flags);
2716   type_add_flags_W (node, flags);
2717 
2718   if (check_type_info_I (NULL, NODE_FUNDAMENTAL_TYPE (node), type_name, info))
2719     type_data_make_W (node, info,
2720 		      check_value_table_I (type_name, info->value_table) ? info->value_table : NULL);
2721   G_WRITE_UNLOCK (&type_rw_lock);
2722 
2723   return NODE_TYPE (node);
2724 }
2725 
2726 /**
2727  * g_type_register_static_simple: (skip)
2728  * @parent_type: type from which this type will be derived
2729  * @type_name: 0-terminated string used as the name of the new type
2730  * @class_size: size of the class structure (see #GTypeInfo)
2731  * @class_init: location of the class initialization function (see #GTypeInfo)
2732  * @instance_size: size of the instance structure (see #GTypeInfo)
2733  * @instance_init: location of the instance initialization function (see #GTypeInfo)
2734  * @flags: bitwise combination of #GTypeFlags values
2735  *
2736  * Registers @type_name as the name of a new static type derived from
2737  * @parent_type.  The value of @flags determines the nature (e.g.
2738  * abstract or not) of the type. It works by filling a #GTypeInfo
2739  * struct and calling g_type_register_static().
2740  *
2741  * Since: 2.12
2742  *
2743  * Returns: the new type identifier
2744  */
2745 GType
g_type_register_static_simple(GType parent_type,const gchar * type_name,guint class_size,GClassInitFunc class_init,guint instance_size,GInstanceInitFunc instance_init,GTypeFlags flags)2746 g_type_register_static_simple (GType             parent_type,
2747 			       const gchar      *type_name,
2748 			       guint             class_size,
2749 			       GClassInitFunc    class_init,
2750 			       guint             instance_size,
2751 			       GInstanceInitFunc instance_init,
2752 			       GTypeFlags	 flags)
2753 {
2754   GTypeInfo info;
2755 
2756   /* Instances are not allowed to be larger than this. If you have a big
2757    * fixed-length array or something, point to it instead.
2758    */
2759   g_return_val_if_fail (class_size <= G_MAXUINT16, G_TYPE_INVALID);
2760   g_return_val_if_fail (instance_size <= G_MAXUINT16, G_TYPE_INVALID);
2761 
2762   info.class_size = class_size;
2763   info.base_init = NULL;
2764   info.base_finalize = NULL;
2765   info.class_init = class_init;
2766   info.class_finalize = NULL;
2767   info.class_data = NULL;
2768   info.instance_size = instance_size;
2769   info.n_preallocs = 0;
2770   info.instance_init = instance_init;
2771   info.value_table = NULL;
2772 
2773   return g_type_register_static (parent_type, type_name, &info, flags);
2774 }
2775 
2776 /**
2777  * g_type_register_static:
2778  * @parent_type: type from which this type will be derived
2779  * @type_name: 0-terminated string used as the name of the new type
2780  * @info: #GTypeInfo structure for this type
2781  * @flags: bitwise combination of #GTypeFlags values
2782  *
2783  * Registers @type_name as the name of a new static type derived from
2784  * @parent_type. The type system uses the information contained in the
2785  * #GTypeInfo structure pointed to by @info to manage the type and its
2786  * instances (if not abstract). The value of @flags determines the nature
2787  * (e.g. abstract or not) of the type.
2788  *
2789  * Returns: the new type identifier
2790  */
2791 GType
g_type_register_static(GType parent_type,const gchar * type_name,const GTypeInfo * info,GTypeFlags flags)2792 g_type_register_static (GType            parent_type,
2793 			const gchar     *type_name,
2794 			const GTypeInfo *info,
2795 			GTypeFlags	 flags)
2796 {
2797   TypeNode *pnode, *node;
2798   GType type = 0;
2799 
2800   g_assert_type_system_initialized ();
2801   g_return_val_if_fail (parent_type > 0, 0);
2802   g_return_val_if_fail (type_name != NULL, 0);
2803   g_return_val_if_fail (info != NULL, 0);
2804 
2805   if (!check_type_name_I (type_name) ||
2806       !check_derivation_I (parent_type, type_name))
2807     return 0;
2808   if (info->class_finalize)
2809     {
2810       g_warning ("class finalizer specified for static type '%s'",
2811 		 type_name);
2812       return 0;
2813     }
2814 
2815   pnode = lookup_type_node_I (parent_type);
2816   G_WRITE_LOCK (&type_rw_lock);
2817   type_data_ref_Wm (pnode);
2818   if (check_type_info_I (pnode, NODE_FUNDAMENTAL_TYPE (pnode), type_name, info))
2819     {
2820       node = type_node_new_W (pnode, type_name, NULL);
2821       type_add_flags_W (node, flags);
2822       type = NODE_TYPE (node);
2823       type_data_make_W (node, info,
2824 			check_value_table_I (type_name, info->value_table) ? info->value_table : NULL);
2825     }
2826   G_WRITE_UNLOCK (&type_rw_lock);
2827 
2828   return type;
2829 }
2830 
2831 /**
2832  * g_type_register_dynamic:
2833  * @parent_type: type from which this type will be derived
2834  * @type_name: 0-terminated string used as the name of the new type
2835  * @plugin: #GTypePlugin structure to retrieve the #GTypeInfo from
2836  * @flags: bitwise combination of #GTypeFlags values
2837  *
2838  * Registers @type_name as the name of a new dynamic type derived from
2839  * @parent_type.  The type system uses the information contained in the
2840  * #GTypePlugin structure pointed to by @plugin to manage the type and its
2841  * instances (if not abstract).  The value of @flags determines the nature
2842  * (e.g. abstract or not) of the type.
2843  *
2844  * Returns: the new type identifier or #G_TYPE_INVALID if registration failed
2845  */
2846 GType
g_type_register_dynamic(GType parent_type,const gchar * type_name,GTypePlugin * plugin,GTypeFlags flags)2847 g_type_register_dynamic (GType        parent_type,
2848 			 const gchar *type_name,
2849 			 GTypePlugin *plugin,
2850 			 GTypeFlags   flags)
2851 {
2852   TypeNode *pnode, *node;
2853   GType type;
2854 
2855   g_assert_type_system_initialized ();
2856   g_return_val_if_fail (parent_type > 0, 0);
2857   g_return_val_if_fail (type_name != NULL, 0);
2858   g_return_val_if_fail (plugin != NULL, 0);
2859 
2860   if (!check_type_name_I (type_name) ||
2861       !check_derivation_I (parent_type, type_name) ||
2862       !check_plugin_U (plugin, TRUE, FALSE, type_name))
2863     return 0;
2864 
2865   G_WRITE_LOCK (&type_rw_lock);
2866   pnode = lookup_type_node_I (parent_type);
2867   node = type_node_new_W (pnode, type_name, plugin);
2868   type_add_flags_W (node, flags);
2869   type = NODE_TYPE (node);
2870   G_WRITE_UNLOCK (&type_rw_lock);
2871 
2872   return type;
2873 }
2874 
2875 /**
2876  * g_type_add_interface_static:
2877  * @instance_type: #GType value of an instantiatable type
2878  * @interface_type: #GType value of an interface type
2879  * @info: #GInterfaceInfo structure for this
2880  *        (@instance_type, @interface_type) combination
2881  *
2882  * Adds @interface_type to the static @instance_type.
2883  * The information contained in the #GInterfaceInfo structure
2884  * pointed to by @info is used to manage the relationship.
2885  */
2886 void
g_type_add_interface_static(GType instance_type,GType interface_type,const GInterfaceInfo * info)2887 g_type_add_interface_static (GType                 instance_type,
2888 			     GType                 interface_type,
2889 			     const GInterfaceInfo *info)
2890 {
2891   /* G_TYPE_IS_INSTANTIATABLE() is an external call: _U */
2892   g_return_if_fail (G_TYPE_IS_INSTANTIATABLE (instance_type));
2893   g_return_if_fail (g_type_parent (interface_type) == G_TYPE_INTERFACE);
2894 
2895   /* we only need to lock class_init_rec_mutex if instance_type already has its
2896    * class initialized, however this function is rarely enough called to take
2897    * the simple route and always acquire class_init_rec_mutex.
2898    */
2899   g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */
2900   G_WRITE_LOCK (&type_rw_lock);
2901   if (check_add_interface_L (instance_type, interface_type))
2902     {
2903       TypeNode *node = lookup_type_node_I (instance_type);
2904       TypeNode *iface = lookup_type_node_I (interface_type);
2905       if (check_interface_info_I (iface, NODE_TYPE (node), info))
2906         type_add_interface_Wm (node, iface, info, NULL);
2907     }
2908   G_WRITE_UNLOCK (&type_rw_lock);
2909   g_rec_mutex_unlock (&class_init_rec_mutex);
2910 }
2911 
2912 /**
2913  * g_type_add_interface_dynamic:
2914  * @instance_type: #GType value of an instantiatable type
2915  * @interface_type: #GType value of an interface type
2916  * @plugin: #GTypePlugin structure to retrieve the #GInterfaceInfo from
2917  *
2918  * Adds @interface_type to the dynamic @instance_type. The information
2919  * contained in the #GTypePlugin structure pointed to by @plugin
2920  * is used to manage the relationship.
2921  */
2922 void
g_type_add_interface_dynamic(GType instance_type,GType interface_type,GTypePlugin * plugin)2923 g_type_add_interface_dynamic (GType        instance_type,
2924 			      GType        interface_type,
2925 			      GTypePlugin *plugin)
2926 {
2927   TypeNode *node;
2928   /* G_TYPE_IS_INSTANTIATABLE() is an external call: _U */
2929   g_return_if_fail (G_TYPE_IS_INSTANTIATABLE (instance_type));
2930   g_return_if_fail (g_type_parent (interface_type) == G_TYPE_INTERFACE);
2931 
2932   node = lookup_type_node_I (instance_type);
2933   if (!check_plugin_U (plugin, FALSE, TRUE, NODE_NAME (node)))
2934     return;
2935 
2936   /* see comment in g_type_add_interface_static() about class_init_rec_mutex */
2937   g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */
2938   G_WRITE_LOCK (&type_rw_lock);
2939   if (check_add_interface_L (instance_type, interface_type))
2940     {
2941       TypeNode *iface = lookup_type_node_I (interface_type);
2942       type_add_interface_Wm (node, iface, NULL, plugin);
2943     }
2944   G_WRITE_UNLOCK (&type_rw_lock);
2945   g_rec_mutex_unlock (&class_init_rec_mutex);
2946 }
2947 
2948 
2949 /* --- public API functions --- */
2950 /**
2951  * g_type_class_ref:
2952  * @type: type ID of a classed type
2953  *
2954  * Increments the reference count of the class structure belonging to
2955  * @type. This function will demand-create the class if it doesn't
2956  * exist already.
2957  *
2958  * Returns: (type GObject.TypeClass) (transfer none): the #GTypeClass
2959  *     structure for the given type ID
2960  */
2961 gpointer
g_type_class_ref(GType type)2962 g_type_class_ref (GType type)
2963 {
2964   TypeNode *node;
2965   GType ptype;
2966   gboolean holds_ref;
2967   GTypeClass *pclass;
2968 
2969   /* optimize for common code path */
2970   node = lookup_type_node_I (type);
2971   if (!node || !node->is_classed)
2972     {
2973       g_warning ("cannot retrieve class for invalid (unclassed) type '%s'",
2974 		 type_descriptive_name_I (type));
2975       return NULL;
2976     }
2977 
2978   if (G_LIKELY (type_data_ref_U (node)))
2979     {
2980       if (G_LIKELY (g_atomic_int_get (&node->data->class.init_state) == INITIALIZED))
2981         return node->data->class.class;
2982       holds_ref = TRUE;
2983     }
2984   else
2985     holds_ref = FALSE;
2986 
2987   /* here, we either have node->data->class.class == NULL, or a recursive
2988    * call to g_type_class_ref() with a partly initialized class, or
2989    * node->data->class.init_state == INITIALIZED, because any
2990    * concurrently running initialization was guarded by class_init_rec_mutex.
2991    */
2992   g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */
2993 
2994   /* we need an initialized parent class for initializing derived classes */
2995   ptype = NODE_PARENT_TYPE (node);
2996   pclass = ptype ? g_type_class_ref (ptype) : NULL;
2997 
2998   G_WRITE_LOCK (&type_rw_lock);
2999 
3000   if (!holds_ref)
3001     type_data_ref_Wm (node);
3002 
3003   if (!node->data->class.class) /* class uninitialized */
3004     type_class_init_Wm (node, pclass);
3005 
3006   G_WRITE_UNLOCK (&type_rw_lock);
3007 
3008   if (pclass)
3009     g_type_class_unref (pclass);
3010 
3011   g_rec_mutex_unlock (&class_init_rec_mutex);
3012 
3013   return node->data->class.class;
3014 }
3015 
3016 /**
3017  * g_type_class_unref:
3018  * @g_class: (type GObject.TypeClass): a #GTypeClass structure to unref
3019  *
3020  * Decrements the reference count of the class structure being passed in.
3021  * Once the last reference count of a class has been released, classes
3022  * may be finalized by the type system, so further dereferencing of a
3023  * class pointer after g_type_class_unref() are invalid.
3024  */
3025 void
g_type_class_unref(gpointer g_class)3026 g_type_class_unref (gpointer g_class)
3027 {
3028   TypeNode *node;
3029   GTypeClass *class = g_class;
3030 
3031   g_return_if_fail (g_class != NULL);
3032 
3033   node = lookup_type_node_I (class->g_type);
3034   if (node && node->is_classed && NODE_REFCOUNT (node))
3035     type_data_unref_U (node, FALSE);
3036   else
3037     g_warning ("cannot unreference class of invalid (unclassed) type '%s'",
3038 	       type_descriptive_name_I (class->g_type));
3039 }
3040 
3041 /**
3042  * g_type_class_unref_uncached: (skip)
3043  * @g_class: (type GObject.TypeClass): a #GTypeClass structure to unref
3044  *
3045  * A variant of g_type_class_unref() for use in #GTypeClassCacheFunc
3046  * implementations. It unreferences a class without consulting the chain
3047  * of #GTypeClassCacheFuncs, avoiding the recursion which would occur
3048  * otherwise.
3049  */
3050 void
g_type_class_unref_uncached(gpointer g_class)3051 g_type_class_unref_uncached (gpointer g_class)
3052 {
3053   TypeNode *node;
3054   GTypeClass *class = g_class;
3055 
3056   g_return_if_fail (g_class != NULL);
3057 
3058   node = lookup_type_node_I (class->g_type);
3059   if (node && node->is_classed && NODE_REFCOUNT (node))
3060     type_data_unref_U (node, TRUE);
3061   else
3062     g_warning ("cannot unreference class of invalid (unclassed) type '%s'",
3063 	       type_descriptive_name_I (class->g_type));
3064 }
3065 
3066 /**
3067  * g_type_class_peek:
3068  * @type: type ID of a classed type
3069  *
3070  * This function is essentially the same as g_type_class_ref(),
3071  * except that the classes reference count isn't incremented.
3072  * As a consequence, this function may return %NULL if the class
3073  * of the type passed in does not currently exist (hasn't been
3074  * referenced before).
3075  *
3076  * Returns: (type GObject.TypeClass) (transfer none): the #GTypeClass
3077  *     structure for the given type ID or %NULL if the class does not
3078  *     currently exist
3079  */
3080 gpointer
g_type_class_peek(GType type)3081 g_type_class_peek (GType type)
3082 {
3083   TypeNode *node;
3084   gpointer class;
3085 
3086   node = lookup_type_node_I (type);
3087   if (node && node->is_classed && NODE_REFCOUNT (node) &&
3088       g_atomic_int_get (&node->data->class.init_state) == INITIALIZED)
3089     /* ref_count _may_ be 0 */
3090     class = node->data->class.class;
3091   else
3092     class = NULL;
3093 
3094   return class;
3095 }
3096 
3097 /**
3098  * g_type_class_peek_static:
3099  * @type: type ID of a classed type
3100  *
3101  * A more efficient version of g_type_class_peek() which works only for
3102  * static types.
3103  *
3104  * Returns: (type GObject.TypeClass) (transfer none): the #GTypeClass
3105  *     structure for the given type ID or %NULL if the class does not
3106  *     currently exist or is dynamically loaded
3107  *
3108  * Since: 2.4
3109  */
3110 gpointer
g_type_class_peek_static(GType type)3111 g_type_class_peek_static (GType type)
3112 {
3113   TypeNode *node;
3114   gpointer class;
3115 
3116   node = lookup_type_node_I (type);
3117   if (node && node->is_classed && NODE_REFCOUNT (node) &&
3118       /* peek only static types: */ node->plugin == NULL &&
3119       g_atomic_int_get (&node->data->class.init_state) == INITIALIZED)
3120     /* ref_count _may_ be 0 */
3121     class = node->data->class.class;
3122   else
3123     class = NULL;
3124 
3125   return class;
3126 }
3127 
3128 /**
3129  * g_type_class_peek_parent:
3130  * @g_class: (type GObject.TypeClass): the #GTypeClass structure to
3131  *     retrieve the parent class for
3132  *
3133  * This is a convenience function often needed in class initializers.
3134  * It returns the class structure of the immediate parent type of the
3135  * class passed in.  Since derived classes hold a reference count on
3136  * their parent classes as long as they are instantiated, the returned
3137  * class will always exist.
3138  *
3139  * This function is essentially equivalent to:
3140  * g_type_class_peek (g_type_parent (G_TYPE_FROM_CLASS (g_class)))
3141  *
3142  * Returns: (type GObject.TypeClass) (transfer none): the parent class
3143  *     of @g_class
3144  */
3145 gpointer
g_type_class_peek_parent(gpointer g_class)3146 g_type_class_peek_parent (gpointer g_class)
3147 {
3148   TypeNode *node;
3149   gpointer class = NULL;
3150 
3151   g_return_val_if_fail (g_class != NULL, NULL);
3152 
3153   node = lookup_type_node_I (G_TYPE_FROM_CLASS (g_class));
3154   /* We used to acquire a read lock here. That is not necessary, since
3155    * parent->data->class.class is constant as long as the derived class
3156    * exists.
3157    */
3158   if (node && node->is_classed && node->data && NODE_PARENT_TYPE (node))
3159     {
3160       node = lookup_type_node_I (NODE_PARENT_TYPE (node));
3161       class = node->data->class.class;
3162     }
3163   else if (NODE_PARENT_TYPE (node))
3164     g_warning (G_STRLOC ": invalid class pointer '%p'", g_class);
3165 
3166   return class;
3167 }
3168 
3169 /**
3170  * g_type_interface_peek:
3171  * @instance_class: (type GObject.TypeClass): a #GTypeClass structure
3172  * @iface_type: an interface ID which this class conforms to
3173  *
3174  * Returns the #GTypeInterface structure of an interface to which the
3175  * passed in class conforms.
3176  *
3177  * Returns: (type GObject.TypeInterface) (transfer none): the #GTypeInterface
3178  *     structure of @iface_type if implemented by @instance_class, %NULL
3179  *     otherwise
3180  */
3181 gpointer
g_type_interface_peek(gpointer instance_class,GType iface_type)3182 g_type_interface_peek (gpointer instance_class,
3183 		       GType    iface_type)
3184 {
3185   TypeNode *node;
3186   TypeNode *iface;
3187   gpointer vtable = NULL;
3188   GTypeClass *class = instance_class;
3189 
3190   g_return_val_if_fail (instance_class != NULL, NULL);
3191 
3192   node = lookup_type_node_I (class->g_type);
3193   iface = lookup_type_node_I (iface_type);
3194   if (node && node->is_instantiatable && iface)
3195     type_lookup_iface_vtable_I (node, iface, &vtable);
3196   else
3197     g_warning (G_STRLOC ": invalid class pointer '%p'", class);
3198 
3199   return vtable;
3200 }
3201 
3202 /**
3203  * g_type_interface_peek_parent:
3204  * @g_iface: (type GObject.TypeInterface): a #GTypeInterface structure
3205  *
3206  * Returns the corresponding #GTypeInterface structure of the parent type
3207  * of the instance type to which @g_iface belongs. This is useful when
3208  * deriving the implementation of an interface from the parent type and
3209  * then possibly overriding some methods.
3210  *
3211  * Returns: (transfer none) (type GObject.TypeInterface): the
3212  *     corresponding #GTypeInterface structure of the parent type of the
3213  *     instance type to which @g_iface belongs, or %NULL if the parent
3214  *     type doesn't conform to the interface
3215  */
3216 gpointer
g_type_interface_peek_parent(gpointer g_iface)3217 g_type_interface_peek_parent (gpointer g_iface)
3218 {
3219   TypeNode *node;
3220   TypeNode *iface;
3221   gpointer vtable = NULL;
3222   GTypeInterface *iface_class = g_iface;
3223 
3224   g_return_val_if_fail (g_iface != NULL, NULL);
3225 
3226   iface = lookup_type_node_I (iface_class->g_type);
3227   node = lookup_type_node_I (iface_class->g_instance_type);
3228   if (node)
3229     node = lookup_type_node_I (NODE_PARENT_TYPE (node));
3230   if (node && node->is_instantiatable && iface)
3231     type_lookup_iface_vtable_I (node, iface, &vtable);
3232   else if (node)
3233     g_warning (G_STRLOC ": invalid interface pointer '%p'", g_iface);
3234 
3235   return vtable;
3236 }
3237 
3238 /**
3239  * g_type_default_interface_ref:
3240  * @g_type: an interface type
3241  *
3242  * Increments the reference count for the interface type @g_type,
3243  * and returns the default interface vtable for the type.
3244  *
3245  * If the type is not currently in use, then the default vtable
3246  * for the type will be created and initialized by calling
3247  * the base interface init and default vtable init functions for
3248  * the type (the @base_init and @class_init members of #GTypeInfo).
3249  * Calling g_type_default_interface_ref() is useful when you
3250  * want to make sure that signals and properties for an interface
3251  * have been installed.
3252  *
3253  * Since: 2.4
3254  *
3255  * Returns: (type GObject.TypeInterface) (transfer none): the default
3256  *     vtable for the interface; call g_type_default_interface_unref()
3257  *     when you are done using the interface.
3258  */
3259 gpointer
g_type_default_interface_ref(GType g_type)3260 g_type_default_interface_ref (GType g_type)
3261 {
3262   TypeNode *node;
3263   gpointer dflt_vtable;
3264 
3265   G_WRITE_LOCK (&type_rw_lock);
3266 
3267   node = lookup_type_node_I (g_type);
3268   if (!node || !NODE_IS_IFACE (node) ||
3269       (node->data && NODE_REFCOUNT (node) == 0))
3270     {
3271       G_WRITE_UNLOCK (&type_rw_lock);
3272       g_warning ("cannot retrieve default vtable for invalid or non-interface type '%s'",
3273 		 type_descriptive_name_I (g_type));
3274       return NULL;
3275     }
3276 
3277   if (!node->data || !node->data->iface.dflt_vtable)
3278     {
3279       G_WRITE_UNLOCK (&type_rw_lock);
3280       g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */
3281       G_WRITE_LOCK (&type_rw_lock);
3282       node = lookup_type_node_I (g_type);
3283       type_data_ref_Wm (node);
3284       type_iface_ensure_dflt_vtable_Wm (node);
3285       g_rec_mutex_unlock (&class_init_rec_mutex);
3286     }
3287   else
3288     type_data_ref_Wm (node); /* ref_count >= 1 already */
3289 
3290   dflt_vtable = node->data->iface.dflt_vtable;
3291   G_WRITE_UNLOCK (&type_rw_lock);
3292 
3293   return dflt_vtable;
3294 }
3295 
3296 /**
3297  * g_type_default_interface_peek:
3298  * @g_type: an interface type
3299  *
3300  * If the interface type @g_type is currently in use, returns its
3301  * default interface vtable.
3302  *
3303  * Since: 2.4
3304  *
3305  * Returns: (type GObject.TypeInterface) (transfer none): the default
3306  *     vtable for the interface, or %NULL if the type is not currently
3307  *     in use
3308  */
3309 gpointer
g_type_default_interface_peek(GType g_type)3310 g_type_default_interface_peek (GType g_type)
3311 {
3312   TypeNode *node;
3313   gpointer vtable;
3314 
3315   node = lookup_type_node_I (g_type);
3316   if (node && NODE_IS_IFACE (node) && NODE_REFCOUNT (node))
3317     vtable = node->data->iface.dflt_vtable;
3318   else
3319     vtable = NULL;
3320 
3321   return vtable;
3322 }
3323 
3324 /**
3325  * g_type_default_interface_unref:
3326  * @g_iface: (type GObject.TypeInterface): the default vtable
3327  *     structure for an interface, as returned by g_type_default_interface_ref()
3328  *
3329  * Decrements the reference count for the type corresponding to the
3330  * interface default vtable @g_iface. If the type is dynamic, then
3331  * when no one is using the interface and all references have
3332  * been released, the finalize function for the interface's default
3333  * vtable (the @class_finalize member of #GTypeInfo) will be called.
3334  *
3335  * Since: 2.4
3336  */
3337 void
g_type_default_interface_unref(gpointer g_iface)3338 g_type_default_interface_unref (gpointer g_iface)
3339 {
3340   TypeNode *node;
3341   GTypeInterface *vtable = g_iface;
3342 
3343   g_return_if_fail (g_iface != NULL);
3344 
3345   node = lookup_type_node_I (vtable->g_type);
3346   if (node && NODE_IS_IFACE (node))
3347     type_data_unref_U (node, FALSE);
3348   else
3349     g_warning ("cannot unreference invalid interface default vtable for '%s'",
3350 	       type_descriptive_name_I (vtable->g_type));
3351 }
3352 
3353 /**
3354  * g_type_name:
3355  * @type: type to return name for
3356  *
3357  * Get the unique name that is assigned to a type ID.  Note that this
3358  * function (like all other GType API) cannot cope with invalid type
3359  * IDs. %G_TYPE_INVALID may be passed to this function, as may be any
3360  * other validly registered type ID, but randomized type IDs should
3361  * not be passed in and will most likely lead to a crash.
3362  *
3363  * Returns: static type name or %NULL
3364  */
3365 const gchar *
g_type_name(GType type)3366 g_type_name (GType type)
3367 {
3368   TypeNode *node;
3369 
3370   g_assert_type_system_initialized ();
3371 
3372   node = lookup_type_node_I (type);
3373 
3374   return node ? NODE_NAME (node) : NULL;
3375 }
3376 
3377 /**
3378  * g_type_qname:
3379  * @type: type to return quark of type name for
3380  *
3381  * Get the corresponding quark of the type IDs name.
3382  *
3383  * Returns: the type names quark or 0
3384  */
3385 GQuark
g_type_qname(GType type)3386 g_type_qname (GType type)
3387 {
3388   TypeNode *node;
3389 
3390   node = lookup_type_node_I (type);
3391 
3392   return node ? node->qname : 0;
3393 }
3394 
3395 /**
3396  * g_type_from_name:
3397  * @name: type name to look up
3398  *
3399  * Look up the type ID from a given type name, returning 0 if no type
3400  * has been registered under this name (this is the preferred method
3401  * to find out by name whether a specific type has been registered
3402  * yet).
3403  *
3404  * Returns: corresponding type ID or 0
3405  */
3406 GType
g_type_from_name(const gchar * name)3407 g_type_from_name (const gchar *name)
3408 {
3409   GType type = 0;
3410 
3411   g_return_val_if_fail (name != NULL, 0);
3412 
3413   G_READ_LOCK (&type_rw_lock);
3414   type = (GType) g_hash_table_lookup (static_type_nodes_ht, name);
3415   G_READ_UNLOCK (&type_rw_lock);
3416 
3417   return type;
3418 }
3419 
3420 /**
3421  * g_type_parent:
3422  * @type: the derived type
3423  *
3424  * Return the direct parent type of the passed in type. If the passed
3425  * in type has no parent, i.e. is a fundamental type, 0 is returned.
3426  *
3427  * Returns: the parent type
3428  */
3429 GType
g_type_parent(GType type)3430 g_type_parent (GType type)
3431 {
3432   TypeNode *node;
3433 
3434   node = lookup_type_node_I (type);
3435 
3436   return node ? NODE_PARENT_TYPE (node) : 0;
3437 }
3438 
3439 /**
3440  * g_type_depth:
3441  * @type: a #GType
3442  *
3443  * Returns the length of the ancestry of the passed in type. This
3444  * includes the type itself, so that e.g. a fundamental type has depth 1.
3445  *
3446  * Returns: the depth of @type
3447  */
3448 guint
g_type_depth(GType type)3449 g_type_depth (GType type)
3450 {
3451   TypeNode *node;
3452 
3453   node = lookup_type_node_I (type);
3454 
3455   return node ? node->n_supers + 1 : 0;
3456 }
3457 
3458 /**
3459  * g_type_next_base:
3460  * @leaf_type: descendant of @root_type and the type to be returned
3461  * @root_type: immediate parent of the returned type
3462  *
3463  * Given a @leaf_type and a @root_type which is contained in its
3464  * ancestry, return the type that @root_type is the immediate parent
3465  * of. In other words, this function determines the type that is
3466  * derived directly from @root_type which is also a base class of
3467  * @leaf_type.  Given a root type and a leaf type, this function can
3468  * be used to determine the types and order in which the leaf type is
3469  * descended from the root type.
3470  *
3471  * Returns: immediate child of @root_type and ancestor of @leaf_type
3472  */
3473 GType
g_type_next_base(GType type,GType base_type)3474 g_type_next_base (GType type,
3475 		  GType base_type)
3476 {
3477   GType atype = 0;
3478   TypeNode *node;
3479 
3480   node = lookup_type_node_I (type);
3481   if (node)
3482     {
3483       TypeNode *base_node = lookup_type_node_I (base_type);
3484 
3485       if (base_node && base_node->n_supers < node->n_supers)
3486 	{
3487 	  guint n = node->n_supers - base_node->n_supers;
3488 
3489 	  if (node->supers[n] == base_type)
3490 	    atype = node->supers[n - 1];
3491 	}
3492     }
3493 
3494   return atype;
3495 }
3496 
3497 static inline gboolean
type_node_check_conformities_UorL(TypeNode * node,TypeNode * iface_node,gboolean support_interfaces,gboolean support_prerequisites,gboolean have_lock)3498 type_node_check_conformities_UorL (TypeNode *node,
3499 				   TypeNode *iface_node,
3500 				   /*        support_inheritance */
3501 				   gboolean  support_interfaces,
3502 				   gboolean  support_prerequisites,
3503 				   gboolean  have_lock)
3504 {
3505   gboolean match;
3506 
3507   if (/* support_inheritance && */
3508       NODE_IS_ANCESTOR (iface_node, node))
3509     return TRUE;
3510 
3511   support_interfaces = support_interfaces && node->is_instantiatable && NODE_IS_IFACE (iface_node);
3512   support_prerequisites = support_prerequisites && NODE_IS_IFACE (node);
3513   match = FALSE;
3514   if (support_interfaces)
3515     {
3516       if (have_lock)
3517 	{
3518 	  if (type_lookup_iface_entry_L (node, iface_node))
3519 	    match = TRUE;
3520 	}
3521       else
3522 	{
3523 	  if (type_lookup_iface_vtable_I (node, iface_node, NULL))
3524 	    match = TRUE;
3525 	}
3526     }
3527   if (!match &&
3528       support_prerequisites)
3529     {
3530       if (!have_lock)
3531 	G_READ_LOCK (&type_rw_lock);
3532       if (support_prerequisites && type_lookup_prerequisite_L (node, NODE_TYPE (iface_node)))
3533 	match = TRUE;
3534       if (!have_lock)
3535 	G_READ_UNLOCK (&type_rw_lock);
3536     }
3537   return match;
3538 }
3539 
3540 static gboolean
type_node_is_a_L(TypeNode * node,TypeNode * iface_node)3541 type_node_is_a_L (TypeNode *node,
3542 		  TypeNode *iface_node)
3543 {
3544   return type_node_check_conformities_UorL (node, iface_node, TRUE, TRUE, TRUE);
3545 }
3546 
3547 static inline gboolean
type_node_conforms_to_U(TypeNode * node,TypeNode * iface_node,gboolean support_interfaces,gboolean support_prerequisites)3548 type_node_conforms_to_U (TypeNode *node,
3549 			 TypeNode *iface_node,
3550 			 gboolean  support_interfaces,
3551 			 gboolean  support_prerequisites)
3552 {
3553   return type_node_check_conformities_UorL (node, iface_node, support_interfaces, support_prerequisites, FALSE);
3554 }
3555 
3556 /**
3557  * g_type_is_a:
3558  * @type: type to check ancestry for
3559  * @is_a_type: possible ancestor of @type or interface that @type
3560  *     could conform to
3561  *
3562  * If @is_a_type is a derivable type, check whether @type is a
3563  * descendant of @is_a_type. If @is_a_type is an interface, check
3564  * whether @type conforms to it.
3565  *
3566  * Returns: %TRUE if @type is a @is_a_type
3567  */
3568 gboolean
g_type_is_a(GType type,GType iface_type)3569 g_type_is_a (GType type,
3570 	     GType iface_type)
3571 {
3572   TypeNode *node, *iface_node;
3573   gboolean is_a;
3574 
3575   if (type == iface_type)
3576     return TRUE;
3577 
3578   node = lookup_type_node_I (type);
3579   iface_node = lookup_type_node_I (iface_type);
3580   is_a = node && iface_node && type_node_conforms_to_U (node, iface_node, TRUE, TRUE);
3581 
3582   return is_a;
3583 }
3584 
3585 /**
3586  * g_type_children:
3587  * @type: the parent type
3588  * @n_children: (out) (optional): location to store the length of
3589  *     the returned array, or %NULL
3590  *
3591  * Return a newly allocated and 0-terminated array of type IDs, listing
3592  * the child types of @type.
3593  *
3594  * Returns: (array length=n_children) (transfer full): Newly allocated
3595  *     and 0-terminated array of child types, free with g_free()
3596  */
3597 GType*
g_type_children(GType type,guint * n_children)3598 g_type_children (GType  type,
3599 		 guint *n_children)
3600 {
3601   TypeNode *node;
3602 
3603   node = lookup_type_node_I (type);
3604   if (node)
3605     {
3606       GType *children;
3607 
3608       G_READ_LOCK (&type_rw_lock);	/* ->children is relocatable */
3609       children = g_new (GType, node->n_children + 1);
3610       if (node->n_children != 0)
3611         memcpy (children, node->children, sizeof (GType) * node->n_children);
3612       children[node->n_children] = 0;
3613 
3614       if (n_children)
3615 	*n_children = node->n_children;
3616       G_READ_UNLOCK (&type_rw_lock);
3617 
3618       return children;
3619     }
3620   else
3621     {
3622       if (n_children)
3623 	*n_children = 0;
3624 
3625       return NULL;
3626     }
3627 }
3628 
3629 /**
3630  * g_type_interfaces:
3631  * @type: the type to list interface types for
3632  * @n_interfaces: (out) (optional): location to store the length of
3633  *     the returned array, or %NULL
3634  *
3635  * Return a newly allocated and 0-terminated array of type IDs, listing
3636  * the interface types that @type conforms to.
3637  *
3638  * Returns: (array length=n_interfaces) (transfer full): Newly allocated
3639  *     and 0-terminated array of interface types, free with g_free()
3640  */
3641 GType*
g_type_interfaces(GType type,guint * n_interfaces)3642 g_type_interfaces (GType  type,
3643 		   guint *n_interfaces)
3644 {
3645   TypeNode *node;
3646 
3647   node = lookup_type_node_I (type);
3648   if (node && node->is_instantiatable)
3649     {
3650       IFaceEntries *entries;
3651       GType *ifaces;
3652       guint i;
3653 
3654       G_READ_LOCK (&type_rw_lock);
3655       entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node);
3656       if (entries)
3657 	{
3658 	  ifaces = g_new (GType, IFACE_ENTRIES_N_ENTRIES (entries) + 1);
3659 	  for (i = 0; i < IFACE_ENTRIES_N_ENTRIES (entries); i++)
3660 	    ifaces[i] = entries->entry[i].iface_type;
3661 	}
3662       else
3663 	{
3664 	  ifaces = g_new (GType, 1);
3665 	  i = 0;
3666 	}
3667       ifaces[i] = 0;
3668 
3669       if (n_interfaces)
3670 	*n_interfaces = i;
3671       G_READ_UNLOCK (&type_rw_lock);
3672 
3673       return ifaces;
3674     }
3675   else
3676     {
3677       if (n_interfaces)
3678 	*n_interfaces = 0;
3679 
3680       return NULL;
3681     }
3682 }
3683 
3684 typedef struct _QData QData;
3685 struct _GData
3686 {
3687   guint  n_qdatas;
3688   QData *qdatas;
3689 };
3690 struct _QData
3691 {
3692   GQuark   quark;
3693   gpointer data;
3694 };
3695 
3696 static inline gpointer
type_get_qdata_L(TypeNode * node,GQuark quark)3697 type_get_qdata_L (TypeNode *node,
3698 		  GQuark    quark)
3699 {
3700   GData *gdata = node->global_gdata;
3701 
3702   if (quark && gdata && gdata->n_qdatas)
3703     {
3704       QData *qdatas = gdata->qdatas - 1;
3705       guint n_qdatas = gdata->n_qdatas;
3706 
3707       do
3708 	{
3709 	  guint i;
3710 	  QData *check;
3711 
3712 	  i = (n_qdatas + 1) / 2;
3713 	  check = qdatas + i;
3714 	  if (quark == check->quark)
3715 	    return check->data;
3716 	  else if (quark > check->quark)
3717 	    {
3718 	      n_qdatas -= i;
3719 	      qdatas = check;
3720 	    }
3721 	  else /* if (quark < check->quark) */
3722 	    n_qdatas = i - 1;
3723 	}
3724       while (n_qdatas);
3725     }
3726   return NULL;
3727 }
3728 
3729 /**
3730  * g_type_get_qdata:
3731  * @type: a #GType
3732  * @quark: a #GQuark id to identify the data
3733  *
3734  * Obtains data which has previously been attached to @type
3735  * with g_type_set_qdata().
3736  *
3737  * Note that this does not take subtyping into account; data
3738  * attached to one type with g_type_set_qdata() cannot
3739  * be retrieved from a subtype using g_type_get_qdata().
3740  *
3741  * Returns: (transfer none): the data, or %NULL if no data was found
3742  */
3743 gpointer
g_type_get_qdata(GType type,GQuark quark)3744 g_type_get_qdata (GType  type,
3745 		  GQuark quark)
3746 {
3747   TypeNode *node;
3748   gpointer data;
3749 
3750   node = lookup_type_node_I (type);
3751   if (node)
3752     {
3753       G_READ_LOCK (&type_rw_lock);
3754       data = type_get_qdata_L (node, quark);
3755       G_READ_UNLOCK (&type_rw_lock);
3756     }
3757   else
3758     {
3759       g_return_val_if_fail (node != NULL, NULL);
3760       data = NULL;
3761     }
3762   return data;
3763 }
3764 
3765 static inline void
type_set_qdata_W(TypeNode * node,GQuark quark,gpointer data)3766 type_set_qdata_W (TypeNode *node,
3767 		  GQuark    quark,
3768 		  gpointer  data)
3769 {
3770   GData *gdata;
3771   QData *qdata;
3772   guint i;
3773 
3774   /* setup qdata list if necessary */
3775   if (!node->global_gdata)
3776     node->global_gdata = g_new0 (GData, 1);
3777   gdata = node->global_gdata;
3778 
3779   /* try resetting old data */
3780   qdata = gdata->qdatas;
3781   for (i = 0; i < gdata->n_qdatas; i++)
3782     if (qdata[i].quark == quark)
3783       {
3784 	qdata[i].data = data;
3785 	return;
3786       }
3787 
3788   /* add new entry */
3789   gdata->n_qdatas++;
3790   gdata->qdatas = g_renew (QData, gdata->qdatas, gdata->n_qdatas);
3791   qdata = gdata->qdatas;
3792   for (i = 0; i < gdata->n_qdatas - 1; i++)
3793     if (qdata[i].quark > quark)
3794       break;
3795   memmove (qdata + i + 1, qdata + i, sizeof (qdata[0]) * (gdata->n_qdatas - i - 1));
3796   qdata[i].quark = quark;
3797   qdata[i].data = data;
3798 }
3799 
3800 /**
3801  * g_type_set_qdata:
3802  * @type: a #GType
3803  * @quark: a #GQuark id to identify the data
3804  * @data: the data
3805  *
3806  * Attaches arbitrary data to a type.
3807  */
3808 void
g_type_set_qdata(GType type,GQuark quark,gpointer data)3809 g_type_set_qdata (GType    type,
3810 		  GQuark   quark,
3811 		  gpointer data)
3812 {
3813   TypeNode *node;
3814 
3815   g_return_if_fail (quark != 0);
3816 
3817   node = lookup_type_node_I (type);
3818   if (node)
3819     {
3820       G_WRITE_LOCK (&type_rw_lock);
3821       type_set_qdata_W (node, quark, data);
3822       G_WRITE_UNLOCK (&type_rw_lock);
3823     }
3824   else
3825     g_return_if_fail (node != NULL);
3826 }
3827 
3828 static void
type_add_flags_W(TypeNode * node,GTypeFlags flags)3829 type_add_flags_W (TypeNode  *node,
3830 		  GTypeFlags flags)
3831 {
3832   guint dflags;
3833 
3834   g_return_if_fail ((flags & ~TYPE_FLAG_MASK) == 0);
3835   g_return_if_fail (node != NULL);
3836 
3837   if ((flags & TYPE_FLAG_MASK) && node->is_classed && node->data && node->data->class.class)
3838     g_warning ("tagging type '%s' as abstract after class initialization", NODE_NAME (node));
3839   dflags = GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags));
3840   dflags |= flags;
3841   type_set_qdata_W (node, static_quark_type_flags, GUINT_TO_POINTER (dflags));
3842 }
3843 
3844 /**
3845  * g_type_query:
3846  * @type: #GType of a static, classed type
3847  * @query: (out caller-allocates): a user provided structure that is
3848  *     filled in with constant values upon success
3849  *
3850  * Queries the type system for information about a specific type.
3851  * This function will fill in a user-provided structure to hold
3852  * type-specific information. If an invalid #GType is passed in, the
3853  * @type member of the #GTypeQuery is 0. All members filled into the
3854  * #GTypeQuery structure should be considered constant and have to be
3855  * left untouched.
3856  */
3857 void
g_type_query(GType type,GTypeQuery * query)3858 g_type_query (GType       type,
3859 	      GTypeQuery *query)
3860 {
3861   TypeNode *node;
3862 
3863   g_return_if_fail (query != NULL);
3864 
3865   /* if node is not static and classed, we won't allow query */
3866   query->type = 0;
3867   node = lookup_type_node_I (type);
3868   if (node && node->is_classed && !node->plugin)
3869     {
3870       /* type is classed and probably even instantiatable */
3871       G_READ_LOCK (&type_rw_lock);
3872       if (node->data)	/* type is static or referenced */
3873 	{
3874 	  query->type = NODE_TYPE (node);
3875 	  query->type_name = NODE_NAME (node);
3876 	  query->class_size = node->data->class.class_size;
3877 	  query->instance_size = node->is_instantiatable ? node->data->instance.instance_size : 0;
3878 	}
3879       G_READ_UNLOCK (&type_rw_lock);
3880     }
3881 }
3882 
3883 /**
3884  * g_type_get_instance_count:
3885  * @type: a #GType
3886  *
3887  * Returns the number of instances allocated of the particular type;
3888  * this is only available if GLib is built with debugging support and
3889  * the instance_count debug flag is set (by setting the GOBJECT_DEBUG
3890  * variable to include instance-count).
3891  *
3892  * Returns: the number of instances allocated of the given type;
3893  *   if instance counts are not available, returns 0.
3894  *
3895  * Since: 2.44
3896  */
3897 int
g_type_get_instance_count(GType type)3898 g_type_get_instance_count (GType type)
3899 {
3900 #ifdef G_ENABLE_DEBUG
3901   TypeNode *node;
3902 
3903   node = lookup_type_node_I (type);
3904   g_return_val_if_fail (node != NULL, 0);
3905 
3906   return g_atomic_int_get (&node->instance_count);
3907 #else
3908   return 0;
3909 #endif
3910 }
3911 
3912 /* --- implementation details --- */
3913 gboolean
g_type_test_flags(GType type,guint flags)3914 g_type_test_flags (GType type,
3915 		   guint flags)
3916 {
3917   TypeNode *node;
3918   gboolean result = FALSE;
3919 
3920   node = lookup_type_node_I (type);
3921   if (node)
3922     {
3923       guint fflags = flags & TYPE_FUNDAMENTAL_FLAG_MASK;
3924       guint tflags = flags & TYPE_FLAG_MASK;
3925 
3926       if (fflags)
3927 	{
3928 	  GTypeFundamentalInfo *finfo = type_node_fundamental_info_I (node);
3929 
3930 	  fflags = (finfo->type_flags & fflags) == fflags;
3931 	}
3932       else
3933 	fflags = TRUE;
3934 
3935       if (tflags)
3936 	{
3937 	  G_READ_LOCK (&type_rw_lock);
3938 	  tflags = (tflags & GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags))) == tflags;
3939 	  G_READ_UNLOCK (&type_rw_lock);
3940 	}
3941       else
3942 	tflags = TRUE;
3943 
3944       result = tflags && fflags;
3945     }
3946 
3947   return result;
3948 }
3949 
3950 /**
3951  * g_type_get_plugin:
3952  * @type: #GType to retrieve the plugin for
3953  *
3954  * Returns the #GTypePlugin structure for @type.
3955  *
3956  * Returns: (transfer none): the corresponding plugin
3957  *     if @type is a dynamic type, %NULL otherwise
3958  */
3959 GTypePlugin*
g_type_get_plugin(GType type)3960 g_type_get_plugin (GType type)
3961 {
3962   TypeNode *node;
3963 
3964   node = lookup_type_node_I (type);
3965 
3966   return node ? node->plugin : NULL;
3967 }
3968 
3969 /**
3970  * g_type_interface_get_plugin:
3971  * @instance_type: #GType of an instantiatable type
3972  * @interface_type: #GType of an interface type
3973  *
3974  * Returns the #GTypePlugin structure for the dynamic interface
3975  * @interface_type which has been added to @instance_type, or %NULL
3976  * if @interface_type has not been added to @instance_type or does
3977  * not have a #GTypePlugin structure. See g_type_add_interface_dynamic().
3978  *
3979  * Returns: (transfer none): the #GTypePlugin for the dynamic
3980  *     interface @interface_type of @instance_type
3981  */
3982 GTypePlugin*
g_type_interface_get_plugin(GType instance_type,GType interface_type)3983 g_type_interface_get_plugin (GType instance_type,
3984 			     GType interface_type)
3985 {
3986   TypeNode *node;
3987   TypeNode *iface;
3988 
3989   g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface_type), NULL);	/* G_TYPE_IS_INTERFACE() is an external call: _U */
3990 
3991   node = lookup_type_node_I (instance_type);
3992   iface = lookup_type_node_I (interface_type);
3993   if (node && iface)
3994     {
3995       IFaceHolder *iholder;
3996       GTypePlugin *plugin;
3997 
3998       G_READ_LOCK (&type_rw_lock);
3999 
4000       iholder = iface_node_get_holders_L (iface);
4001       while (iholder && iholder->instance_type != instance_type)
4002 	iholder = iholder->next;
4003       plugin = iholder ? iholder->plugin : NULL;
4004 
4005       G_READ_UNLOCK (&type_rw_lock);
4006 
4007       return plugin;
4008     }
4009 
4010   g_return_val_if_fail (node == NULL, NULL);
4011   g_return_val_if_fail (iface == NULL, NULL);
4012 
4013   g_warning (G_STRLOC ": attempt to look up plugin for invalid instance/interface type pair.");
4014 
4015   return NULL;
4016 }
4017 
4018 /**
4019  * g_type_fundamental_next:
4020  *
4021  * Returns the next free fundamental type id which can be used to
4022  * register a new fundamental type with g_type_register_fundamental().
4023  * The returned type ID represents the highest currently registered
4024  * fundamental type identifier.
4025  *
4026  * Returns: the next available fundamental type ID to be registered,
4027  *     or 0 if the type system ran out of fundamental type IDs
4028  */
4029 GType
g_type_fundamental_next(void)4030 g_type_fundamental_next (void)
4031 {
4032   GType type;
4033 
4034   G_READ_LOCK (&type_rw_lock);
4035   type = static_fundamental_next;
4036   G_READ_UNLOCK (&type_rw_lock);
4037   type = G_TYPE_MAKE_FUNDAMENTAL (type);
4038   return type <= G_TYPE_FUNDAMENTAL_MAX ? type : 0;
4039 }
4040 
4041 /**
4042  * g_type_fundamental:
4043  * @type_id: valid type ID
4044  *
4045  * Internal function, used to extract the fundamental type ID portion.
4046  * Use G_TYPE_FUNDAMENTAL() instead.
4047  *
4048  * Returns: fundamental type ID
4049  */
4050 GType
g_type_fundamental(GType type_id)4051 g_type_fundamental (GType type_id)
4052 {
4053   TypeNode *node = lookup_type_node_I (type_id);
4054 
4055   return node ? NODE_FUNDAMENTAL_TYPE (node) : 0;
4056 }
4057 
4058 gboolean
g_type_check_instance_is_a(GTypeInstance * type_instance,GType iface_type)4059 g_type_check_instance_is_a (GTypeInstance *type_instance,
4060 			    GType          iface_type)
4061 {
4062   TypeNode *node, *iface;
4063   gboolean check;
4064 
4065   if (!type_instance || !type_instance->g_class)
4066     return FALSE;
4067 
4068   node = lookup_type_node_I (type_instance->g_class->g_type);
4069   iface = lookup_type_node_I (iface_type);
4070   check = node && node->is_instantiatable && iface && type_node_conforms_to_U (node, iface, TRUE, FALSE);
4071 
4072   return check;
4073 }
4074 
4075 gboolean
g_type_check_instance_is_fundamentally_a(GTypeInstance * type_instance,GType fundamental_type)4076 g_type_check_instance_is_fundamentally_a (GTypeInstance *type_instance,
4077                                           GType          fundamental_type)
4078 {
4079   TypeNode *node;
4080   if (!type_instance || !type_instance->g_class)
4081     return FALSE;
4082   node = lookup_type_node_I (type_instance->g_class->g_type);
4083   return node && (NODE_FUNDAMENTAL_TYPE(node) == fundamental_type);
4084 }
4085 
4086 gboolean
g_type_check_class_is_a(GTypeClass * type_class,GType is_a_type)4087 g_type_check_class_is_a (GTypeClass *type_class,
4088 			 GType       is_a_type)
4089 {
4090   TypeNode *node, *iface;
4091   gboolean check;
4092 
4093   if (!type_class)
4094     return FALSE;
4095 
4096   node = lookup_type_node_I (type_class->g_type);
4097   iface = lookup_type_node_I (is_a_type);
4098   check = node && node->is_classed && iface && type_node_conforms_to_U (node, iface, FALSE, FALSE);
4099 
4100   return check;
4101 }
4102 
4103 GTypeInstance*
g_type_check_instance_cast(GTypeInstance * type_instance,GType iface_type)4104 g_type_check_instance_cast (GTypeInstance *type_instance,
4105 			    GType          iface_type)
4106 {
4107   if (type_instance)
4108     {
4109       if (type_instance->g_class)
4110 	{
4111 	  TypeNode *node, *iface;
4112 	  gboolean is_instantiatable, check;
4113 
4114 	  node = lookup_type_node_I (type_instance->g_class->g_type);
4115 	  is_instantiatable = node && node->is_instantiatable;
4116 	  iface = lookup_type_node_I (iface_type);
4117 	  check = is_instantiatable && iface && type_node_conforms_to_U (node, iface, TRUE, FALSE);
4118 	  if (check)
4119 	    return type_instance;
4120 
4121 	  if (is_instantiatable)
4122 	    g_warning ("invalid cast from '%s' to '%s'",
4123 		       type_descriptive_name_I (type_instance->g_class->g_type),
4124 		       type_descriptive_name_I (iface_type));
4125 	  else
4126 	    g_warning ("invalid uninstantiatable type '%s' in cast to '%s'",
4127 		       type_descriptive_name_I (type_instance->g_class->g_type),
4128 		       type_descriptive_name_I (iface_type));
4129 	}
4130       else
4131 	g_warning ("invalid unclassed pointer in cast to '%s'",
4132 		   type_descriptive_name_I (iface_type));
4133     }
4134 
4135   return type_instance;
4136 }
4137 
4138 GTypeClass*
g_type_check_class_cast(GTypeClass * type_class,GType is_a_type)4139 g_type_check_class_cast (GTypeClass *type_class,
4140 			 GType       is_a_type)
4141 {
4142   if (type_class)
4143     {
4144       TypeNode *node, *iface;
4145       gboolean is_classed, check;
4146 
4147       node = lookup_type_node_I (type_class->g_type);
4148       is_classed = node && node->is_classed;
4149       iface = lookup_type_node_I (is_a_type);
4150       check = is_classed && iface && type_node_conforms_to_U (node, iface, FALSE, FALSE);
4151       if (check)
4152 	return type_class;
4153 
4154       if (is_classed)
4155 	g_warning ("invalid class cast from '%s' to '%s'",
4156 		   type_descriptive_name_I (type_class->g_type),
4157 		   type_descriptive_name_I (is_a_type));
4158       else
4159 	g_warning ("invalid unclassed type '%s' in class cast to '%s'",
4160 		   type_descriptive_name_I (type_class->g_type),
4161 		   type_descriptive_name_I (is_a_type));
4162     }
4163   else
4164     g_warning ("invalid class cast from (NULL) pointer to '%s'",
4165 	       type_descriptive_name_I (is_a_type));
4166   return type_class;
4167 }
4168 
4169 /**
4170  * g_type_check_instance:
4171  * @instance: a valid #GTypeInstance structure
4172  *
4173  * Private helper function to aid implementation of the
4174  * G_TYPE_CHECK_INSTANCE() macro.
4175  *
4176  * Returns: %TRUE if @instance is valid, %FALSE otherwise
4177  */
4178 gboolean
g_type_check_instance(GTypeInstance * type_instance)4179 g_type_check_instance (GTypeInstance *type_instance)
4180 {
4181   /* this function is just here to make the signal system
4182    * conveniently elaborated on instance checks
4183    */
4184   if (type_instance)
4185     {
4186       if (type_instance->g_class)
4187 	{
4188 	  TypeNode *node = lookup_type_node_I (type_instance->g_class->g_type);
4189 
4190 	  if (node && node->is_instantiatable)
4191 	    return TRUE;
4192 
4193 	  g_warning ("instance of invalid non-instantiatable type '%s'",
4194 		     type_descriptive_name_I (type_instance->g_class->g_type));
4195 	}
4196       else
4197 	g_warning ("instance with invalid (NULL) class pointer");
4198     }
4199   else
4200     g_warning ("invalid (NULL) pointer instance");
4201 
4202   return FALSE;
4203 }
4204 
4205 static inline gboolean
type_check_is_value_type_U(GType type)4206 type_check_is_value_type_U (GType type)
4207 {
4208   GTypeFlags tflags = G_TYPE_FLAG_VALUE_ABSTRACT;
4209   TypeNode *node;
4210 
4211   /* common path speed up */
4212   node = lookup_type_node_I (type);
4213   if (node && node->mutatable_check_cache)
4214     return TRUE;
4215 
4216   G_READ_LOCK (&type_rw_lock);
4217  restart_check:
4218   if (node)
4219     {
4220       if (node->data && NODE_REFCOUNT (node) > 0 &&
4221 	  node->data->common.value_table->value_init)
4222 	tflags = GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags));
4223       else if (NODE_IS_IFACE (node))
4224 	{
4225 	  guint i;
4226 
4227 	  for (i = 0; i < IFACE_NODE_N_PREREQUISITES (node); i++)
4228 	    {
4229 	      GType prtype = IFACE_NODE_PREREQUISITES (node)[i];
4230 	      TypeNode *prnode = lookup_type_node_I (prtype);
4231 
4232 	      if (prnode->is_instantiatable)
4233 		{
4234 		  type = prtype;
4235 		  node = lookup_type_node_I (type);
4236 		  goto restart_check;
4237 		}
4238 	    }
4239 	}
4240     }
4241   G_READ_UNLOCK (&type_rw_lock);
4242 
4243   return !(tflags & G_TYPE_FLAG_VALUE_ABSTRACT);
4244 }
4245 
4246 gboolean
g_type_check_is_value_type(GType type)4247 g_type_check_is_value_type (GType type)
4248 {
4249   return type_check_is_value_type_U (type);
4250 }
4251 
4252 gboolean
g_type_check_value(const GValue * value)4253 g_type_check_value (const GValue *value)
4254 {
4255   return value && type_check_is_value_type_U (value->g_type);
4256 }
4257 
4258 gboolean
g_type_check_value_holds(const GValue * value,GType type)4259 g_type_check_value_holds (const GValue *value,
4260 			  GType         type)
4261 {
4262   return value && type_check_is_value_type_U (value->g_type) && g_type_is_a (value->g_type, type);
4263 }
4264 
4265 /**
4266  * g_type_value_table_peek: (skip)
4267  * @type: a #GType
4268  *
4269  * Returns the location of the #GTypeValueTable associated with @type.
4270  *
4271  * Note that this function should only be used from source code
4272  * that implements or has internal knowledge of the implementation of
4273  * @type.
4274  *
4275  * Returns: location of the #GTypeValueTable associated with @type or
4276  *     %NULL if there is no #GTypeValueTable associated with @type
4277  */
4278 GTypeValueTable*
g_type_value_table_peek(GType type)4279 g_type_value_table_peek (GType type)
4280 {
4281   GTypeValueTable *vtable = NULL;
4282   TypeNode *node = lookup_type_node_I (type);
4283   gboolean has_refed_data, has_table;
4284 
4285   if (node && NODE_REFCOUNT (node) && node->mutatable_check_cache)
4286     return node->data->common.value_table;
4287 
4288   G_READ_LOCK (&type_rw_lock);
4289 
4290  restart_table_peek:
4291   has_refed_data = node && node->data && NODE_REFCOUNT (node) > 0;
4292   has_table = has_refed_data && node->data->common.value_table->value_init;
4293   if (has_refed_data)
4294     {
4295       if (has_table)
4296 	vtable = node->data->common.value_table;
4297       else if (NODE_IS_IFACE (node))
4298 	{
4299 	  guint i;
4300 
4301 	  for (i = 0; i < IFACE_NODE_N_PREREQUISITES (node); i++)
4302 	    {
4303 	      GType prtype = IFACE_NODE_PREREQUISITES (node)[i];
4304 	      TypeNode *prnode = lookup_type_node_I (prtype);
4305 
4306 	      if (prnode->is_instantiatable)
4307 		{
4308 		  type = prtype;
4309 		  node = lookup_type_node_I (type);
4310 		  goto restart_table_peek;
4311 		}
4312 	    }
4313 	}
4314     }
4315 
4316   G_READ_UNLOCK (&type_rw_lock);
4317 
4318   if (vtable)
4319     return vtable;
4320 
4321   if (!node)
4322     g_warning (G_STRLOC ": type id '%" G_GSIZE_FORMAT "' is invalid", type);
4323   if (!has_refed_data)
4324     g_warning ("can't peek value table for type '%s' which is not currently referenced",
4325 	       type_descriptive_name_I (type));
4326 
4327   return NULL;
4328 }
4329 
4330 const gchar *
g_type_name_from_instance(GTypeInstance * instance)4331 g_type_name_from_instance (GTypeInstance *instance)
4332 {
4333   if (!instance)
4334     return "<NULL-instance>";
4335   else
4336     return g_type_name_from_class (instance->g_class);
4337 }
4338 
4339 const gchar *
g_type_name_from_class(GTypeClass * g_class)4340 g_type_name_from_class (GTypeClass *g_class)
4341 {
4342   if (!g_class)
4343     return "<NULL-class>";
4344   else
4345     return g_type_name (g_class->g_type);
4346 }
4347 
4348 
4349 /* --- private api for gboxed.c --- */
4350 gpointer
_g_type_boxed_copy(GType type,gpointer value)4351 _g_type_boxed_copy (GType type, gpointer value)
4352 {
4353   TypeNode *node = lookup_type_node_I (type);
4354 
4355   return node->data->boxed.copy_func (value);
4356 }
4357 
4358 void
_g_type_boxed_free(GType type,gpointer value)4359 _g_type_boxed_free (GType type, gpointer value)
4360 {
4361   TypeNode *node = lookup_type_node_I (type);
4362 
4363   node->data->boxed.free_func (value);
4364 }
4365 
4366 void
_g_type_boxed_init(GType type,GBoxedCopyFunc copy_func,GBoxedFreeFunc free_func)4367 _g_type_boxed_init (GType          type,
4368                     GBoxedCopyFunc copy_func,
4369                     GBoxedFreeFunc free_func)
4370 {
4371   TypeNode *node = lookup_type_node_I (type);
4372 
4373   node->data->boxed.copy_func = copy_func;
4374   node->data->boxed.free_func = free_func;
4375 }
4376 
4377 /* --- initialization --- */
4378 /**
4379  * g_type_init_with_debug_flags:
4380  * @debug_flags: bitwise combination of #GTypeDebugFlags values for
4381  *     debugging purposes
4382  *
4383  * This function used to initialise the type system with debugging
4384  * flags.  Since GLib 2.36, the type system is initialised automatically
4385  * and this function does nothing.
4386  *
4387  * If you need to enable debugging features, use the GOBJECT_DEBUG
4388  * environment variable.
4389  *
4390  * Deprecated: 2.36: the type system is now initialised automatically
4391  */
4392 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
4393 void
g_type_init_with_debug_flags(GTypeDebugFlags debug_flags)4394 g_type_init_with_debug_flags (GTypeDebugFlags debug_flags)
4395 {
4396   g_assert_type_system_initialized ();
4397 
4398   if (debug_flags)
4399     g_message ("g_type_init_with_debug_flags() is no longer supported.  Use the GOBJECT_DEBUG environment variable.");
4400 }
4401 G_GNUC_END_IGNORE_DEPRECATIONS
4402 
4403 /**
4404  * g_type_init:
4405  *
4406  * This function used to initialise the type system.  Since GLib 2.36,
4407  * the type system is initialised automatically and this function does
4408  * nothing.
4409  *
4410  * Deprecated: 2.36: the type system is now initialised automatically
4411  */
4412 void
g_type_init(void)4413 g_type_init (void)
4414 {
4415   g_assert_type_system_initialized ();
4416 }
4417 
4418 static void
gobject_init(void)4419 gobject_init (void)
4420 {
4421   const gchar *env_string;
4422   GTypeInfo info;
4423   TypeNode *node;
4424   GType type G_GNUC_UNUSED  /* when compiling with G_DISABLE_ASSERT */;
4425 
4426   /* Ensure GLib is initialized first, see
4427    * https://bugzilla.gnome.org/show_bug.cgi?id=756139
4428    */
4429   GLIB_PRIVATE_CALL (glib_init) ();
4430 
4431   G_WRITE_LOCK (&type_rw_lock);
4432 
4433   /* setup GObject library wide debugging flags */
4434   env_string = g_getenv ("GOBJECT_DEBUG");
4435   if (env_string != NULL)
4436     {
4437       GDebugKey debug_keys[] = {
4438         { "objects", G_TYPE_DEBUG_OBJECTS },
4439         { "instance-count", G_TYPE_DEBUG_INSTANCE_COUNT },
4440         { "signals", G_TYPE_DEBUG_SIGNALS },
4441       };
4442 
4443       _g_type_debug_flags = g_parse_debug_string (env_string, debug_keys, G_N_ELEMENTS (debug_keys));
4444     }
4445 
4446   /* quarks */
4447   static_quark_type_flags = g_quark_from_static_string ("-g-type-private--GTypeFlags");
4448   static_quark_iface_holder = g_quark_from_static_string ("-g-type-private--IFaceHolder");
4449   static_quark_dependants_array = g_quark_from_static_string ("-g-type-private--dependants-array");
4450 
4451   /* type qname hash table */
4452   static_type_nodes_ht = g_hash_table_new (g_str_hash, g_str_equal);
4453 
4454   /* invalid type G_TYPE_INVALID (0)
4455    */
4456   static_fundamental_type_nodes[0] = NULL;
4457 
4458   /* void type G_TYPE_NONE
4459    */
4460   node = type_node_fundamental_new_W (G_TYPE_NONE, g_intern_static_string ("void"), 0);
4461   type = NODE_TYPE (node);
4462   g_assert (type == G_TYPE_NONE);
4463 
4464   /* interface fundamental type G_TYPE_INTERFACE (!classed)
4465    */
4466   memset (&info, 0, sizeof (info));
4467   node = type_node_fundamental_new_W (G_TYPE_INTERFACE, g_intern_static_string ("GInterface"), G_TYPE_FLAG_DERIVABLE);
4468   type = NODE_TYPE (node);
4469   type_data_make_W (node, &info, NULL);
4470   g_assert (type == G_TYPE_INTERFACE);
4471 
4472   G_WRITE_UNLOCK (&type_rw_lock);
4473 
4474   _g_value_c_init ();
4475 
4476   /* G_TYPE_TYPE_PLUGIN
4477    */
4478   g_type_ensure (g_type_plugin_get_type ());
4479 
4480   /* G_TYPE_* value types
4481    */
4482   _g_value_types_init ();
4483 
4484   /* G_TYPE_ENUM & G_TYPE_FLAGS
4485    */
4486   _g_enum_types_init ();
4487 
4488   /* G_TYPE_BOXED
4489    */
4490   _g_boxed_type_init ();
4491 
4492   /* G_TYPE_PARAM
4493    */
4494   _g_param_type_init ();
4495 
4496   /* G_TYPE_OBJECT
4497    */
4498   _g_object_type_init ();
4499 
4500   /* G_TYPE_PARAM_* pspec types
4501    */
4502   _g_param_spec_types_init ();
4503 
4504   /* Value Transformations
4505    */
4506   _g_value_transforms_init ();
4507 
4508   /* Signal system
4509    */
4510   _g_signal_init ();
4511 }
4512 
4513 #if defined (G_OS_WIN32)
4514 
4515 BOOL WINAPI DllMain (HINSTANCE hinstDLL,
4516                      DWORD     fdwReason,
4517                      LPVOID    lpvReserved);
4518 
4519 BOOL WINAPI
DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)4520 DllMain (HINSTANCE hinstDLL,
4521          DWORD     fdwReason,
4522          LPVOID    lpvReserved)
4523 {
4524   switch (fdwReason)
4525     {
4526     case DLL_PROCESS_ATTACH:
4527       gobject_init ();
4528       break;
4529 
4530     default:
4531       /* do nothing */
4532       ;
4533     }
4534 
4535   return TRUE;
4536 }
4537 
4538 #elif defined (G_HAS_CONSTRUCTORS)
4539 #ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
4540 #pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(gobject_init_ctor)
4541 #endif
G_DEFINE_CONSTRUCTOR(gobject_init_ctor)4542 G_DEFINE_CONSTRUCTOR(gobject_init_ctor)
4543 
4544 static void
4545 gobject_init_ctor (void)
4546 {
4547   gobject_init ();
4548 }
4549 
4550 #else
4551 # error Your platform/compiler is missing constructor support
4552 #endif
4553 
4554 /**
4555  * g_type_class_add_private:
4556  * @g_class: (type GObject.TypeClass): class structure for an instantiatable
4557  *    type
4558  * @private_size: size of private structure
4559  *
4560  * Registers a private structure for an instantiatable type.
4561  *
4562  * When an object is allocated, the private structures for
4563  * the type and all of its parent types are allocated
4564  * sequentially in the same memory block as the public
4565  * structures, and are zero-filled.
4566  *
4567  * Note that the accumulated size of the private structures of
4568  * a type and all its parent types cannot exceed 64 KiB.
4569  *
4570  * This function should be called in the type's class_init() function.
4571  * The private structure can be retrieved using the
4572  * G_TYPE_INSTANCE_GET_PRIVATE() macro.
4573  *
4574  * The following example shows attaching a private structure
4575  * MyObjectPrivate to an object MyObject defined in the standard
4576  * GObject fashion in the type's class_init() function.
4577  *
4578  * Note the use of a structure member "priv" to avoid the overhead
4579  * of repeatedly calling MY_OBJECT_GET_PRIVATE().
4580  *
4581  * |[<!-- language="C" -->
4582  * typedef struct _MyObject        MyObject;
4583  * typedef struct _MyObjectPrivate MyObjectPrivate;
4584  *
4585  * struct _MyObject {
4586  *  GObject parent;
4587  *
4588  *  MyObjectPrivate *priv;
4589  * };
4590  *
4591  * struct _MyObjectPrivate {
4592  *   int some_field;
4593  * };
4594  *
4595  * static void
4596  * my_object_class_init (MyObjectClass *klass)
4597  * {
4598  *   g_type_class_add_private (klass, sizeof (MyObjectPrivate));
4599  * }
4600  *
4601  * static void
4602  * my_object_init (MyObject *my_object)
4603  * {
4604  *   my_object->priv = G_TYPE_INSTANCE_GET_PRIVATE (my_object,
4605  *                                                  MY_TYPE_OBJECT,
4606  *                                                  MyObjectPrivate);
4607  *   // my_object->priv->some_field will be automatically initialised to 0
4608  * }
4609  *
4610  * static int
4611  * my_object_get_some_field (MyObject *my_object)
4612  * {
4613  *   MyObjectPrivate *priv;
4614  *
4615  *   g_return_val_if_fail (MY_IS_OBJECT (my_object), 0);
4616  *
4617  *   priv = my_object->priv;
4618  *
4619  *   return priv->some_field;
4620  * }
4621  * ]|
4622  *
4623  * Since: 2.4
4624  * Deprecated: 2.58: Use the G_ADD_PRIVATE() macro with the `G_DEFINE_*`
4625  *   family of macros to add instance private data to a type
4626  */
4627 void
g_type_class_add_private(gpointer g_class,gsize private_size)4628 g_type_class_add_private (gpointer g_class,
4629 			  gsize    private_size)
4630 {
4631   GType instance_type = ((GTypeClass *)g_class)->g_type;
4632   TypeNode *node = lookup_type_node_I (instance_type);
4633 
4634   g_return_if_fail (private_size > 0);
4635   g_return_if_fail (private_size <= 0xffff);
4636 
4637   if (!node || !node->is_instantiatable || !node->data || node->data->class.class != g_class)
4638     {
4639       g_warning ("cannot add private field to invalid (non-instantiatable) type '%s'",
4640 		 type_descriptive_name_I (instance_type));
4641       return;
4642     }
4643 
4644   if (NODE_PARENT_TYPE (node))
4645     {
4646       TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
4647       if (node->data->instance.private_size != pnode->data->instance.private_size)
4648 	{
4649 	  g_warning ("g_type_class_add_private() called multiple times for the same type");
4650 	  return;
4651 	}
4652     }
4653 
4654   G_WRITE_LOCK (&type_rw_lock);
4655 
4656   private_size = ALIGN_STRUCT (node->data->instance.private_size + private_size);
4657   g_assert (private_size <= 0xffff);
4658   node->data->instance.private_size = private_size;
4659 
4660   G_WRITE_UNLOCK (&type_rw_lock);
4661 }
4662 
4663 /* semi-private, called only by the G_ADD_PRIVATE macro */
4664 gint
g_type_add_instance_private(GType class_gtype,gsize private_size)4665 g_type_add_instance_private (GType class_gtype,
4666                              gsize private_size)
4667 {
4668   TypeNode *node = lookup_type_node_I (class_gtype);
4669 
4670   g_return_val_if_fail (private_size > 0, 0);
4671   g_return_val_if_fail (private_size <= 0xffff, 0);
4672 
4673   if (!node || !node->is_classed || !node->is_instantiatable || !node->data)
4674     {
4675       g_warning ("cannot add private field to invalid (non-instantiatable) type '%s'",
4676 		 type_descriptive_name_I (class_gtype));
4677       return 0;
4678     }
4679 
4680   if (node->plugin != NULL)
4681     {
4682       g_warning ("cannot use g_type_add_instance_private() with dynamic type '%s'",
4683                  type_descriptive_name_I (class_gtype));
4684       return 0;
4685     }
4686 
4687   /* in the future, we want to register the private data size of a type
4688    * directly from the get_type() implementation so that we can take full
4689    * advantage of the type definition macros that we already have.
4690    *
4691    * unfortunately, this does not behave correctly if a class in the middle
4692    * of the type hierarchy uses the "old style" of private data registration
4693    * from the class_init() implementation, as the private data offset is not
4694    * going to be known until the full class hierarchy is initialized.
4695    *
4696    * in order to transition our code to the Glorious New Future™, we proceed
4697    * with a two-step implementation: first, we provide this new function to
4698    * register the private data size in the get_type() implementation and we
4699    * hide it behind a macro. the function will return the private size, instead
4700    * of the offset, which will be stored inside a static variable defined by
4701    * the G_DEFINE_TYPE_EXTENDED macro. the G_DEFINE_TYPE_EXTENDED macro will
4702    * check the variable and call g_type_class_add_instance_private(), which
4703    * will use the data size and actually register the private data, then
4704    * return the computed offset of the private data, which will be stored
4705    * inside the static variable, so we can use it to retrieve the pointer
4706    * to the private data structure.
4707    *
4708    * once all our code has been migrated to the new idiomatic form of private
4709    * data registration, we will change the g_type_add_instance_private()
4710    * function to actually perform the registration and return the offset
4711    * of the private data; g_type_class_add_instance_private() already checks
4712    * if the passed argument is negative (meaning that it's an offset in the
4713    * GTypeInstance allocation) and becomes a no-op if that's the case. this
4714    * should make the migration fully transparent even if we're effectively
4715    * copying this macro into everybody's code.
4716    */
4717   return private_size;
4718 }
4719 
4720 /* semi-private function, should only be used by G_DEFINE_TYPE_EXTENDED */
4721 void
g_type_class_adjust_private_offset(gpointer g_class,gint * private_size_or_offset)4722 g_type_class_adjust_private_offset (gpointer  g_class,
4723                                     gint     *private_size_or_offset)
4724 {
4725   GType class_gtype = ((GTypeClass *) g_class)->g_type;
4726   TypeNode *node = lookup_type_node_I (class_gtype);
4727   gssize private_size;
4728 
4729   g_return_if_fail (private_size_or_offset != NULL);
4730 
4731   /* if we have been passed the offset instead of the private data size,
4732    * then we consider this as a no-op, and just return the value. see the
4733    * comment in g_type_add_instance_private() for the full explanation.
4734    */
4735   if (*private_size_or_offset > 0)
4736     g_return_if_fail (*private_size_or_offset <= 0xffff);
4737   else
4738     return;
4739 
4740   if (!node || !node->is_classed || !node->is_instantiatable || !node->data)
4741     {
4742       g_warning ("cannot add private field to invalid (non-instantiatable) type '%s'",
4743 		 type_descriptive_name_I (class_gtype));
4744       *private_size_or_offset = 0;
4745       return;
4746     }
4747 
4748   if (NODE_PARENT_TYPE (node))
4749     {
4750       TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
4751       if (node->data->instance.private_size != pnode->data->instance.private_size)
4752 	{
4753 	  g_warning ("g_type_add_instance_private() called multiple times for the same type");
4754           *private_size_or_offset = 0;
4755 	  return;
4756 	}
4757     }
4758 
4759   G_WRITE_LOCK (&type_rw_lock);
4760 
4761   private_size = ALIGN_STRUCT (node->data->instance.private_size + *private_size_or_offset);
4762   g_assert (private_size <= 0xffff);
4763   node->data->instance.private_size = private_size;
4764 
4765   *private_size_or_offset = -(gint) node->data->instance.private_size;
4766 
4767   G_WRITE_UNLOCK (&type_rw_lock);
4768 }
4769 
4770 gpointer
g_type_instance_get_private(GTypeInstance * instance,GType private_type)4771 g_type_instance_get_private (GTypeInstance *instance,
4772 			     GType          private_type)
4773 {
4774   TypeNode *node;
4775 
4776   g_return_val_if_fail (instance != NULL && instance->g_class != NULL, NULL);
4777 
4778   node = lookup_type_node_I (private_type);
4779   if (G_UNLIKELY (!node || !node->is_instantiatable))
4780     {
4781       g_warning ("instance of invalid non-instantiatable type '%s'",
4782                  type_descriptive_name_I (instance->g_class->g_type));
4783       return NULL;
4784     }
4785 
4786   return ((gchar *) instance) - node->data->instance.private_size;
4787 }
4788 
4789 /**
4790  * g_type_class_get_instance_private_offset: (skip)
4791  * @g_class: (type GObject.TypeClass): a #GTypeClass
4792  *
4793  * Gets the offset of the private data for instances of @g_class.
4794  *
4795  * This is how many bytes you should add to the instance pointer of a
4796  * class in order to get the private data for the type represented by
4797  * @g_class.
4798  *
4799  * You can only call this function after you have registered a private
4800  * data area for @g_class using g_type_class_add_private().
4801  *
4802  * Returns: the offset, in bytes
4803  *
4804  * Since: 2.38
4805  **/
4806 gint
g_type_class_get_instance_private_offset(gpointer g_class)4807 g_type_class_get_instance_private_offset (gpointer g_class)
4808 {
4809   GType instance_type;
4810   guint16 parent_size;
4811   TypeNode *node;
4812 
4813   g_assert (g_class != NULL);
4814 
4815   instance_type = ((GTypeClass *) g_class)->g_type;
4816   node = lookup_type_node_I (instance_type);
4817 
4818   g_assert (node != NULL);
4819   g_assert (node->is_instantiatable);
4820 
4821   if (NODE_PARENT_TYPE (node))
4822     {
4823       TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
4824 
4825       parent_size = pnode->data->instance.private_size;
4826     }
4827   else
4828     parent_size = 0;
4829 
4830   if (node->data->instance.private_size == parent_size)
4831     g_error ("g_type_class_get_instance_private_offset() called on class %s but it has no private data",
4832              g_type_name (instance_type));
4833 
4834   return -(gint) node->data->instance.private_size;
4835 }
4836 
4837 /**
4838  * g_type_add_class_private:
4839  * @class_type: GType of a classed type
4840  * @private_size: size of private structure
4841  *
4842  * Registers a private class structure for a classed type;
4843  * when the class is allocated, the private structures for
4844  * the class and all of its parent types are allocated
4845  * sequentially in the same memory block as the public
4846  * structures, and are zero-filled.
4847  *
4848  * This function should be called in the
4849  * type's get_type() function after the type is registered.
4850  * The private structure can be retrieved using the
4851  * G_TYPE_CLASS_GET_PRIVATE() macro.
4852  *
4853  * Since: 2.24
4854  */
4855 void
g_type_add_class_private(GType class_type,gsize private_size)4856 g_type_add_class_private (GType    class_type,
4857 			  gsize    private_size)
4858 {
4859   TypeNode *node = lookup_type_node_I (class_type);
4860   gsize offset;
4861 
4862   g_return_if_fail (private_size > 0);
4863 
4864   if (!node || !node->is_classed || !node->data)
4865     {
4866       g_warning ("cannot add class private field to invalid type '%s'",
4867 		 type_descriptive_name_I (class_type));
4868       return;
4869     }
4870 
4871   if (NODE_PARENT_TYPE (node))
4872     {
4873       TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
4874       if (node->data->class.class_private_size != pnode->data->class.class_private_size)
4875 	{
4876 	  g_warning ("g_type_add_class_private() called multiple times for the same type");
4877 	  return;
4878 	}
4879     }
4880 
4881   G_WRITE_LOCK (&type_rw_lock);
4882 
4883   offset = ALIGN_STRUCT (node->data->class.class_private_size);
4884   node->data->class.class_private_size = offset + private_size;
4885 
4886   G_WRITE_UNLOCK (&type_rw_lock);
4887 }
4888 
4889 gpointer
g_type_class_get_private(GTypeClass * klass,GType private_type)4890 g_type_class_get_private (GTypeClass *klass,
4891 			  GType       private_type)
4892 {
4893   TypeNode *class_node;
4894   TypeNode *private_node;
4895   TypeNode *parent_node;
4896   gsize offset;
4897 
4898   g_return_val_if_fail (klass != NULL, NULL);
4899 
4900   class_node = lookup_type_node_I (klass->g_type);
4901   if (G_UNLIKELY (!class_node || !class_node->is_classed))
4902     {
4903       g_warning ("class of invalid type '%s'",
4904 		 type_descriptive_name_I (klass->g_type));
4905       return NULL;
4906     }
4907 
4908   private_node = lookup_type_node_I (private_type);
4909   if (G_UNLIKELY (!private_node || !NODE_IS_ANCESTOR (private_node, class_node)))
4910     {
4911       g_warning ("attempt to retrieve private data for invalid type '%s'",
4912 		 type_descriptive_name_I (private_type));
4913       return NULL;
4914     }
4915 
4916   offset = ALIGN_STRUCT (class_node->data->class.class_size);
4917 
4918   if (NODE_PARENT_TYPE (private_node))
4919     {
4920       parent_node = lookup_type_node_I (NODE_PARENT_TYPE (private_node));
4921       g_assert (parent_node->data && NODE_REFCOUNT (parent_node) > 0);
4922 
4923       if (G_UNLIKELY (private_node->data->class.class_private_size == parent_node->data->class.class_private_size))
4924 	{
4925 	  g_warning ("g_type_instance_get_class_private() requires a prior call to g_type_add_class_private()");
4926 	  return NULL;
4927 	}
4928 
4929       offset += ALIGN_STRUCT (parent_node->data->class.class_private_size);
4930     }
4931 
4932   return G_STRUCT_MEMBER_P (klass, offset);
4933 }
4934 
4935 /**
4936  * g_type_ensure:
4937  * @type: a #GType
4938  *
4939  * Ensures that the indicated @type has been registered with the
4940  * type system, and its _class_init() method has been run.
4941  *
4942  * In theory, simply calling the type's _get_type() method (or using
4943  * the corresponding macro) is supposed take care of this. However,
4944  * _get_type() methods are often marked %G_GNUC_CONST for performance
4945  * reasons, even though this is technically incorrect (since
4946  * %G_GNUC_CONST requires that the function not have side effects,
4947  * which _get_type() methods do on the first call). As a result, if
4948  * you write a bare call to a _get_type() macro, it may get optimized
4949  * out by the compiler. Using g_type_ensure() guarantees that the
4950  * type's _get_type() method is called.
4951  *
4952  * Since: 2.34
4953  */
4954 void
g_type_ensure(GType type)4955 g_type_ensure (GType type)
4956 {
4957   /* In theory, @type has already been resolved and so there's nothing
4958    * to do here. But this protects us in the case where the function
4959    * gets inlined (as it might in gobject_init_ctor() above).
4960    */
4961   if (G_UNLIKELY (type == (GType)-1))
4962     g_error ("can't happen");
4963 }
4964