Imported Upstream version 2.67.1
[platform/upstream/glib.git] / gobject / gtype.c
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   guint 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*
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
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*
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*
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*
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*
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*
576 lookup_iface_entry_I (IFaceEntries *entries,
577                       TypeNode     *iface_node)
578 {
579   guint8 *offsets;
580   guint 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*
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
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
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*
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
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
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
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
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
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
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*
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
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
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
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
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
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
1282 iface_node_has_available_offset_L (TypeNode *iface_node,
1283                                    int 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 int
1303 find_free_iface_offset_L (IFaceEntries *entries)
1304 {
1305   IFaceEntry *entry;
1306   TypeNode *iface_node;
1307   int offset;
1308   int i;
1309   int n_entries;
1310
1311   n_entries = IFACE_ENTRIES_N_ENTRIES (entries);
1312   offset = -1;
1313   do
1314     {
1315       offset++;
1316       for (i = 0; i < n_entries; i++)
1317         {
1318           entry = &entries->entry[i];
1319           iface_node = lookup_type_node_I (entry->iface_type);
1320
1321           if (!iface_node_has_available_offset_L (iface_node, offset, i))
1322             break;
1323         }
1324     }
1325   while (i != n_entries);
1326
1327   return offset;
1328 }
1329
1330 static void
1331 iface_node_set_offset_L (TypeNode *iface_node,
1332                          int offset,
1333                          int index)
1334 {
1335   guint8 *offsets, *old_offsets;
1336   int new_size, old_size;
1337   int i;
1338
1339   old_offsets = G_ATOMIC_ARRAY_GET_LOCKED (&iface_node->_prot.offsets, guint8);
1340   if (old_offsets == NULL)
1341     old_size = 0;
1342   else
1343     {
1344       old_size = G_ATOMIC_ARRAY_DATA_SIZE (old_offsets);
1345       if (offset < old_size &&
1346           old_offsets[offset] == index + 1)
1347         return; /* Already set to this index, return */
1348     }
1349   new_size = MAX (old_size, offset + 1);
1350
1351   offsets = _g_atomic_array_copy (&iface_node->_prot.offsets,
1352                                   0, new_size - old_size);
1353
1354   /* Mark new area as unused */
1355   for (i = old_size; i < new_size; i++)
1356     offsets[i] = 0;
1357
1358   offsets[offset] = index + 1;
1359
1360   _g_atomic_array_update (&iface_node->_prot.offsets, offsets);
1361 }
1362
1363 static void
1364 type_node_add_iface_entry_W (TypeNode   *node,
1365                              GType       iface_type,
1366                              IFaceEntry *parent_entry)
1367 {
1368   IFaceEntries *entries;
1369   IFaceEntry *entry;
1370   TypeNode *iface_node;
1371   guint i, j;
1372   guint num_entries;
1373
1374   g_assert (node->is_instantiatable);
1375
1376   entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node);
1377   if (entries != NULL)
1378     {
1379       num_entries = IFACE_ENTRIES_N_ENTRIES (entries);
1380
1381       g_assert (num_entries < MAX_N_INTERFACES);
1382
1383       for (i = 0; i < num_entries; i++)
1384         {
1385           entry = &entries->entry[i];
1386           if (entry->iface_type == iface_type)
1387             {
1388               /* this can happen in two cases:
1389                * - our parent type already conformed to iface_type and node
1390                *   got its own holder info. here, our children already have
1391                *   entries and NULL vtables, since this will only work for
1392                *   uninitialized classes.
1393                * - an interface type is added to an ancestor after it was
1394                *   added to a child type.
1395                */
1396               if (!parent_entry)
1397                 g_assert (entry->vtable == NULL && entry->init_state == UNINITIALIZED);
1398               else
1399                 {
1400                   /* sick, interface is added to ancestor *after* child type;
1401                    * nothing todo, the entry and our children were already setup correctly
1402                    */
1403                 }
1404               return;
1405             }
1406         }
1407     }
1408
1409   entries = _g_atomic_array_copy (CLASSED_NODE_IFACES_ENTRIES (node),
1410                                   IFACE_ENTRIES_HEADER_SIZE,
1411                                   sizeof (IFaceEntry));
1412   num_entries = IFACE_ENTRIES_N_ENTRIES (entries);
1413   i = num_entries - 1;
1414   if (i == 0)
1415     entries->offset_index = 0;
1416   entries->entry[i].iface_type = iface_type;
1417   entries->entry[i].vtable = NULL;
1418   entries->entry[i].init_state = UNINITIALIZED;
1419
1420   if (parent_entry)
1421     {
1422       if (node->data && g_atomic_int_get (&node->data->class.init_state) >= BASE_IFACE_INIT)
1423         {
1424           entries->entry[i].init_state = INITIALIZED;
1425           entries->entry[i].vtable = parent_entry->vtable;
1426         }
1427     }
1428
1429   /* Update offsets in iface */
1430   iface_node = lookup_type_node_I (iface_type);
1431
1432   if (iface_node_has_available_offset_L (iface_node,
1433                                          entries->offset_index,
1434                                          i))
1435     {
1436       iface_node_set_offset_L (iface_node,
1437                                entries->offset_index, i);
1438     }
1439   else
1440    {
1441       entries->offset_index =
1442         find_free_iface_offset_L (entries);
1443       for (j = 0; j < IFACE_ENTRIES_N_ENTRIES (entries); j++)
1444         {
1445           entry = &entries->entry[j];
1446           iface_node =
1447             lookup_type_node_I (entry->iface_type);
1448           iface_node_set_offset_L (iface_node,
1449                                    entries->offset_index, j);
1450         }
1451     }
1452
1453   _g_atomic_array_update (CLASSED_NODE_IFACES_ENTRIES (node), entries);
1454
1455   if (parent_entry)
1456     {
1457       for (i = 0; i < node->n_children; i++)
1458         type_node_add_iface_entry_W (lookup_type_node_I (node->children[i]), iface_type, &entries->entry[i]);
1459     }
1460 }
1461
1462 static void
1463 type_add_interface_Wm (TypeNode             *node,
1464                        TypeNode             *iface,
1465                        const GInterfaceInfo *info,
1466                        GTypePlugin          *plugin)
1467 {
1468   IFaceHolder *iholder = g_new0 (IFaceHolder, 1);
1469   IFaceEntry *entry;
1470   guint i;
1471
1472   g_assert (node->is_instantiatable && NODE_IS_IFACE (iface) && ((info && !plugin) || (!info && plugin)));
1473   
1474   iholder->next = iface_node_get_holders_L (iface);
1475   iface_node_set_holders_W (iface, iholder);
1476   iholder->instance_type = NODE_TYPE (node);
1477   iholder->info = info ? g_memdup (info, sizeof (*info)) : NULL;
1478   iholder->plugin = plugin;
1479
1480   /* create an iface entry for this type */
1481   type_node_add_iface_entry_W (node, NODE_TYPE (iface), NULL);
1482   
1483   /* if the class is already (partly) initialized, we may need to base
1484    * initialize and/or initialize the new interface.
1485    */
1486   if (node->data)
1487     {
1488       InitState class_state = g_atomic_int_get (&node->data->class.init_state);
1489       
1490       if (class_state >= BASE_IFACE_INIT)
1491         type_iface_vtable_base_init_Wm (iface, node);
1492       
1493       if (class_state >= IFACE_INIT)
1494         type_iface_vtable_iface_init_Wm (iface, node);
1495     }
1496   
1497   /* create iface entries for children of this type */
1498   entry = type_lookup_iface_entry_L (node, iface);
1499   for (i = 0; i < node->n_children; i++)
1500     type_node_add_iface_entry_W (lookup_type_node_I (node->children[i]), NODE_TYPE (iface), entry);
1501 }
1502
1503 static void
1504 type_iface_add_prerequisite_W (TypeNode *iface,
1505                                TypeNode *prerequisite_node)
1506 {
1507   GType prerequisite_type = NODE_TYPE (prerequisite_node);
1508   GType *prerequisites, *dependants;
1509   guint n_dependants, i;
1510   
1511   g_assert (NODE_IS_IFACE (iface) &&
1512             IFACE_NODE_N_PREREQUISITES (iface) < MAX_N_PREREQUISITES &&
1513             (prerequisite_node->is_instantiatable || NODE_IS_IFACE (prerequisite_node)));
1514   
1515   prerequisites = IFACE_NODE_PREREQUISITES (iface);
1516   for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++)
1517     if (prerequisites[i] == prerequisite_type)
1518       return;                   /* we already have that prerequisiste */
1519     else if (prerequisites[i] > prerequisite_type)
1520       break;
1521   IFACE_NODE_N_PREREQUISITES (iface) += 1;
1522   IFACE_NODE_PREREQUISITES (iface) = g_renew (GType,
1523                                               IFACE_NODE_PREREQUISITES (iface),
1524                                               IFACE_NODE_N_PREREQUISITES (iface));
1525   prerequisites = IFACE_NODE_PREREQUISITES (iface);
1526   memmove (prerequisites + i + 1, prerequisites + i,
1527            sizeof (prerequisites[0]) * (IFACE_NODE_N_PREREQUISITES (iface) - i - 1));
1528   prerequisites[i] = prerequisite_type;
1529   
1530   /* we want to get notified when prerequisites get added to prerequisite_node */
1531   if (NODE_IS_IFACE (prerequisite_node))
1532     {
1533       dependants = iface_node_get_dependants_array_L (prerequisite_node);
1534       n_dependants = dependants ? dependants[0] : 0;
1535       n_dependants += 1;
1536       dependants = g_renew (GType, dependants, n_dependants + 1);
1537       dependants[n_dependants] = NODE_TYPE (iface);
1538       dependants[0] = n_dependants;
1539       iface_node_set_dependants_array_W (prerequisite_node, dependants);
1540     }
1541   
1542   /* we need to notify all dependants */
1543   dependants = iface_node_get_dependants_array_L (iface);
1544   n_dependants = dependants ? dependants[0] : 0;
1545   for (i = 1; i <= n_dependants; i++)
1546     type_iface_add_prerequisite_W (lookup_type_node_I (dependants[i]), prerequisite_node);
1547 }
1548
1549 /**
1550  * g_type_interface_add_prerequisite:
1551  * @interface_type: #GType value of an interface type
1552  * @prerequisite_type: #GType value of an interface or instantiatable type
1553  *
1554  * Adds @prerequisite_type to the list of prerequisites of @interface_type.
1555  * This means that any type implementing @interface_type must also implement
1556  * @prerequisite_type. Prerequisites can be thought of as an alternative to
1557  * interface derivation (which GType doesn't support). An interface can have
1558  * at most one instantiatable prerequisite type.
1559  */
1560 void
1561 g_type_interface_add_prerequisite (GType interface_type,
1562                                    GType prerequisite_type)
1563 {
1564   TypeNode *iface, *prerequisite_node;
1565   IFaceHolder *holders;
1566   
1567   g_return_if_fail (G_TYPE_IS_INTERFACE (interface_type));      /* G_TYPE_IS_INTERFACE() is an external call: _U */
1568   g_return_if_fail (!g_type_is_a (interface_type, prerequisite_type));
1569   g_return_if_fail (!g_type_is_a (prerequisite_type, interface_type));
1570   
1571   iface = lookup_type_node_I (interface_type);
1572   prerequisite_node = lookup_type_node_I (prerequisite_type);
1573   if (!iface || !prerequisite_node || !NODE_IS_IFACE (iface))
1574     {
1575       g_warning ("interface type '%s' or prerequisite type '%s' invalid",
1576                  type_descriptive_name_I (interface_type),
1577                  type_descriptive_name_I (prerequisite_type));
1578       return;
1579     }
1580   G_WRITE_LOCK (&type_rw_lock);
1581   holders = iface_node_get_holders_L (iface);
1582   if (holders)
1583     {
1584       G_WRITE_UNLOCK (&type_rw_lock);
1585       g_warning ("unable to add prerequisite '%s' to interface '%s' which is already in use for '%s'",
1586                  type_descriptive_name_I (prerequisite_type),
1587                  type_descriptive_name_I (interface_type),
1588                  type_descriptive_name_I (holders->instance_type));
1589       return;
1590     }
1591   if (prerequisite_node->is_instantiatable)
1592     {
1593       guint i;
1594       
1595       /* can have at most one publicly installable instantiatable prerequisite */
1596       for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++)
1597         {
1598           TypeNode *prnode = lookup_type_node_I (IFACE_NODE_PREREQUISITES (iface)[i]);
1599           
1600           if (prnode->is_instantiatable)
1601             {
1602               G_WRITE_UNLOCK (&type_rw_lock);
1603               g_warning ("adding prerequisite '%s' to interface '%s' conflicts with existing prerequisite '%s'",
1604                          type_descriptive_name_I (prerequisite_type),
1605                          type_descriptive_name_I (interface_type),
1606                          type_descriptive_name_I (NODE_TYPE (prnode)));
1607               return;
1608             }
1609         }
1610       
1611       for (i = 0; i < prerequisite_node->n_supers + 1u; i++)
1612         type_iface_add_prerequisite_W (iface, lookup_type_node_I (prerequisite_node->supers[i]));
1613       G_WRITE_UNLOCK (&type_rw_lock);
1614     }
1615   else if (NODE_IS_IFACE (prerequisite_node))
1616     {
1617       GType *prerequisites;
1618       guint i;
1619       
1620       prerequisites = IFACE_NODE_PREREQUISITES (prerequisite_node);
1621       for (i = 0; i < IFACE_NODE_N_PREREQUISITES (prerequisite_node); i++)
1622         type_iface_add_prerequisite_W (iface, lookup_type_node_I (prerequisites[i]));
1623       type_iface_add_prerequisite_W (iface, prerequisite_node);
1624       G_WRITE_UNLOCK (&type_rw_lock);
1625     }
1626   else
1627     {
1628       G_WRITE_UNLOCK (&type_rw_lock);
1629       g_warning ("prerequisite '%s' for interface '%s' is neither instantiatable nor interface",
1630                  type_descriptive_name_I (prerequisite_type),
1631                  type_descriptive_name_I (interface_type));
1632     }
1633 }
1634
1635 /**
1636  * g_type_interface_prerequisites:
1637  * @interface_type: an interface type
1638  * @n_prerequisites: (out) (optional): location to return the number
1639  *     of prerequisites, or %NULL
1640  *
1641  * Returns the prerequisites of an interfaces type.
1642  *
1643  * Since: 2.2
1644  *
1645  * Returns: (array length=n_prerequisites) (transfer full): a
1646  *     newly-allocated zero-terminated array of #GType containing
1647  *     the prerequisites of @interface_type
1648  */
1649 GType*
1650 g_type_interface_prerequisites (GType  interface_type,
1651                                 guint *n_prerequisites)
1652 {
1653   TypeNode *iface;
1654   
1655   g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface_type), NULL);
1656
1657   iface = lookup_type_node_I (interface_type);
1658   if (iface)
1659     {
1660       GType *types;
1661       TypeNode *inode = NULL;
1662       guint i, n = 0;
1663       
1664       G_READ_LOCK (&type_rw_lock);
1665       types = g_new0 (GType, IFACE_NODE_N_PREREQUISITES (iface) + 1);
1666       for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++)
1667         {
1668           GType prerequisite = IFACE_NODE_PREREQUISITES (iface)[i];
1669           TypeNode *node = lookup_type_node_I (prerequisite);
1670           if (node->is_instantiatable)
1671             {
1672               if (!inode || type_node_is_a_L (node, inode))
1673                 inode = node;
1674             }
1675           else
1676             types[n++] = NODE_TYPE (node);
1677         }
1678       if (inode)
1679         types[n++] = NODE_TYPE (inode);
1680       
1681       if (n_prerequisites)
1682         *n_prerequisites = n;
1683       G_READ_UNLOCK (&type_rw_lock);
1684       
1685       return types;
1686     }
1687   else
1688     {
1689       if (n_prerequisites)
1690         *n_prerequisites = 0;
1691       
1692       return NULL;
1693     }
1694 }
1695
1696 /**
1697  * g_type_interface_instantiatable_prerequisite:
1698  * @interface_type: an interface type
1699  *
1700  * Returns the most specific instantiatable prerequisite of an
1701  * interface type. If the interface type has no instantiatable
1702  * prerequisite, %G_TYPE_INVALID is returned.
1703  *
1704  * See g_type_interface_add_prerequisite() for more information
1705  * about prerequisites.
1706  *
1707  * Returns: the instantiatable prerequisite type or %G_TYPE_INVALID if none
1708  *
1709  * Since: 2.68
1710  **/
1711 GType
1712 g_type_interface_instantiatable_prerequisite (GType interface_type)
1713 {
1714   TypeNode *inode = NULL;
1715   TypeNode *iface;
1716   guint i;
1717
1718   g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface_type), G_TYPE_INVALID);
1719
1720   iface = lookup_type_node_I (interface_type);
1721   if (iface == NULL)
1722     return G_TYPE_INVALID;
1723
1724   G_READ_LOCK (&type_rw_lock);
1725
1726   for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++)
1727     {
1728       GType prerequisite = IFACE_NODE_PREREQUISITES (iface)[i];
1729       TypeNode *node = lookup_type_node_I (prerequisite);
1730       if (node->is_instantiatable)
1731         {
1732           if (!inode || type_node_is_a_L (node, inode))
1733             inode = node;
1734         }
1735     }
1736
1737   G_READ_UNLOCK (&type_rw_lock);
1738
1739   if (inode)
1740     return NODE_TYPE (inode);
1741   else
1742     return G_TYPE_INVALID;
1743 }
1744
1745 static IFaceHolder*
1746 type_iface_peek_holder_L (TypeNode *iface,
1747                           GType     instance_type)
1748 {
1749   IFaceHolder *iholder;
1750   
1751   g_assert (NODE_IS_IFACE (iface));
1752   
1753   iholder = iface_node_get_holders_L (iface);
1754   while (iholder && iholder->instance_type != instance_type)
1755     iholder = iholder->next;
1756   return iholder;
1757 }
1758
1759 static IFaceHolder*
1760 type_iface_retrieve_holder_info_Wm (TypeNode *iface,
1761                                     GType     instance_type,
1762                                     gboolean  need_info)
1763 {
1764   IFaceHolder *iholder = type_iface_peek_holder_L (iface, instance_type);
1765   
1766   if (iholder && !iholder->info && need_info)
1767     {
1768       GInterfaceInfo tmp_info;
1769       
1770       g_assert (iholder->plugin != NULL);
1771       
1772       type_data_ref_Wm (iface);
1773       if (iholder->info)
1774         INVALID_RECURSION ("g_type_plugin_*", iface->plugin, NODE_NAME (iface));
1775       
1776       memset (&tmp_info, 0, sizeof (tmp_info));
1777       
1778       G_WRITE_UNLOCK (&type_rw_lock);
1779       g_type_plugin_use (iholder->plugin);
1780       g_type_plugin_complete_interface_info (iholder->plugin, instance_type, NODE_TYPE (iface), &tmp_info);
1781       G_WRITE_LOCK (&type_rw_lock);
1782       if (iholder->info)
1783         INVALID_RECURSION ("g_type_plugin_*", iholder->plugin, NODE_NAME (iface));
1784       
1785       check_interface_info_I (iface, instance_type, &tmp_info);
1786       iholder->info = g_memdup (&tmp_info, sizeof (tmp_info));
1787     }
1788   
1789   return iholder;       /* we don't modify write lock upon returning NULL */
1790 }
1791
1792 static void
1793 type_iface_blow_holder_info_Wm (TypeNode *iface,
1794                                 GType     instance_type)
1795 {
1796   IFaceHolder *iholder = iface_node_get_holders_L (iface);
1797   
1798   g_assert (NODE_IS_IFACE (iface));
1799   
1800   while (iholder->instance_type != instance_type)
1801     iholder = iholder->next;
1802   
1803   if (iholder->info && iholder->plugin)
1804     {
1805       g_free (iholder->info);
1806       iholder->info = NULL;
1807       
1808       G_WRITE_UNLOCK (&type_rw_lock);
1809       g_type_plugin_unuse (iholder->plugin);
1810       type_data_unref_U (iface, FALSE);
1811       G_WRITE_LOCK (&type_rw_lock);
1812     }
1813 }
1814
1815 /**
1816  * g_type_create_instance: (skip)
1817  * @type: an instantiatable type to create an instance for
1818  *
1819  * Creates and initializes an instance of @type if @type is valid and
1820  * can be instantiated. The type system only performs basic allocation
1821  * and structure setups for instances: actual instance creation should
1822  * happen through functions supplied by the type's fundamental type
1823  * implementation.  So use of g_type_create_instance() is reserved for
1824  * implementers of fundamental types only. E.g. instances of the
1825  * #GObject hierarchy should be created via g_object_new() and never
1826  * directly through g_type_create_instance() which doesn't handle things
1827  * like singleton objects or object construction.
1828  *
1829  * The extended members of the returned instance are guaranteed to be filled
1830  * with zeros.
1831  *
1832  * Note: Do not use this function, unless you're implementing a
1833  * fundamental type. Also language bindings should not use this
1834  * function, but g_object_new() instead.
1835  *
1836  * Returns: an allocated and initialized instance, subject to further
1837  *     treatment by the fundamental type implementation
1838  */
1839 GTypeInstance*
1840 g_type_create_instance (GType type)
1841 {
1842   TypeNode *node;
1843   GTypeInstance *instance;
1844   GTypeClass *class;
1845   gchar *allocated;
1846   gint private_size;
1847   gint ivar_size;
1848   guint i;
1849
1850   node = lookup_type_node_I (type);
1851   if (!node || !node->is_instantiatable)
1852     {
1853       g_error ("cannot create new instance of invalid (non-instantiatable) type '%s'",
1854                  type_descriptive_name_I (type));
1855     }
1856   /* G_TYPE_IS_ABSTRACT() is an external call: _U */
1857   if (!node->mutatable_check_cache && G_TYPE_IS_ABSTRACT (type))
1858     {
1859       g_error ("cannot create instance of abstract (non-instantiatable) type '%s'",
1860                  type_descriptive_name_I (type));
1861     }
1862   
1863   class = g_type_class_ref (type);
1864
1865   /* We allocate the 'private' areas before the normal instance data, in
1866    * reverse order.  This allows the private area of a particular class
1867    * to always be at a constant relative address to the instance data.
1868    * If we stored the private data after the instance data this would
1869    * not be the case (since a subclass that added more instance
1870    * variables would push the private data further along).
1871    *
1872    * This presents problems for valgrindability, of course, so we do a
1873    * workaround for that case.  We identify the start of the object to
1874    * valgrind as an allocated block (so that pointers to objects show up
1875    * as 'reachable' instead of 'possibly lost').  We then add an extra
1876    * pointer at the end of the object, after all instance data, back to
1877    * the start of the private area so that it is also recorded as
1878    * reachable.  We also add extra private space at the start because
1879    * valgrind doesn't seem to like us claiming to have allocated an
1880    * address that it saw allocated by malloc().
1881    */
1882   private_size = node->data->instance.private_size;
1883   ivar_size = node->data->instance.instance_size;
1884
1885 #ifdef ENABLE_VALGRIND
1886   if (private_size && RUNNING_ON_VALGRIND)
1887     {
1888       private_size += ALIGN_STRUCT (1);
1889
1890       /* Allocate one extra pointer size... */
1891       allocated = g_slice_alloc0 (private_size + ivar_size + sizeof (gpointer));
1892       /* ... and point it back to the start of the private data. */
1893       *(gpointer *) (allocated + private_size + ivar_size) = allocated + ALIGN_STRUCT (1);
1894
1895       /* Tell valgrind that it should treat the object itself as such */
1896       VALGRIND_MALLOCLIKE_BLOCK (allocated + private_size, ivar_size + sizeof (gpointer), 0, TRUE);
1897       VALGRIND_MALLOCLIKE_BLOCK (allocated + ALIGN_STRUCT (1), private_size - ALIGN_STRUCT (1), 0, TRUE);
1898     }
1899   else
1900 #endif
1901     allocated = g_slice_alloc0 (private_size + ivar_size);
1902
1903   instance = (GTypeInstance *) (allocated + private_size);
1904
1905   for (i = node->n_supers; i > 0; i--)
1906     {
1907       TypeNode *pnode;
1908       
1909       pnode = lookup_type_node_I (node->supers[i]);
1910       if (pnode->data->instance.instance_init)
1911         {
1912           instance->g_class = pnode->data->instance.class;
1913           pnode->data->instance.instance_init (instance, class);
1914         }
1915     }
1916
1917   instance->g_class = class;
1918   if (node->data->instance.instance_init)
1919     node->data->instance.instance_init (instance, class);
1920
1921 #ifdef  G_ENABLE_DEBUG
1922   IF_DEBUG (INSTANCE_COUNT)
1923     {
1924       g_atomic_int_inc ((int *) &node->instance_count);
1925     }
1926 #endif
1927
1928   TRACE(GOBJECT_OBJECT_NEW(instance, type));
1929
1930   return instance;
1931 }
1932
1933 /**
1934  * g_type_free_instance:
1935  * @instance: an instance of a type
1936  *
1937  * Frees an instance of a type, returning it to the instance pool for
1938  * the type, if there is one.
1939  *
1940  * Like g_type_create_instance(), this function is reserved for
1941  * implementors of fundamental types.
1942  */
1943 void
1944 g_type_free_instance (GTypeInstance *instance)
1945 {
1946   TypeNode *node;
1947   GTypeClass *class;
1948   gchar *allocated;
1949   gint private_size;
1950   gint ivar_size;
1951
1952   g_return_if_fail (instance != NULL && instance->g_class != NULL);
1953   
1954   class = instance->g_class;
1955   node = lookup_type_node_I (class->g_type);
1956   if (!node || !node->is_instantiatable || !node->data || node->data->class.class != (gpointer) class)
1957     {
1958       g_warning ("cannot free instance of invalid (non-instantiatable) type '%s'",
1959                  type_descriptive_name_I (class->g_type));
1960       return;
1961     }
1962   /* G_TYPE_IS_ABSTRACT() is an external call: _U */
1963   if (!node->mutatable_check_cache && G_TYPE_IS_ABSTRACT (NODE_TYPE (node)))
1964     {
1965       g_warning ("cannot free instance of abstract (non-instantiatable) type '%s'",
1966                  NODE_NAME (node));
1967       return;
1968     }
1969   
1970   instance->g_class = NULL;
1971   private_size = node->data->instance.private_size;
1972   ivar_size = node->data->instance.instance_size;
1973   allocated = ((gchar *) instance) - private_size;
1974
1975 #ifdef G_ENABLE_DEBUG
1976   memset (allocated, 0xaa, ivar_size + private_size);
1977 #endif
1978
1979 #ifdef ENABLE_VALGRIND
1980   /* See comment in g_type_create_instance() about what's going on here.
1981    * We're basically unwinding what we put into motion there.
1982    */
1983   if (private_size && RUNNING_ON_VALGRIND)
1984     {
1985       private_size += ALIGN_STRUCT (1);
1986       allocated -= ALIGN_STRUCT (1);
1987
1988       /* Clear out the extra pointer... */
1989       *(gpointer *) (allocated + private_size + ivar_size) = NULL;
1990       /* ... and ensure we include it in the size we free. */
1991       g_slice_free1 (private_size + ivar_size + sizeof (gpointer), allocated);
1992
1993       VALGRIND_FREELIKE_BLOCK (allocated + ALIGN_STRUCT (1), 0);
1994       VALGRIND_FREELIKE_BLOCK (instance, 0);
1995     }
1996   else
1997 #endif
1998     g_slice_free1 (private_size + ivar_size, allocated);
1999
2000 #ifdef  G_ENABLE_DEBUG
2001   IF_DEBUG (INSTANCE_COUNT)
2002     {
2003       g_atomic_int_add ((int *) &node->instance_count, -1);
2004     }
2005 #endif
2006
2007   g_type_class_unref (class);
2008 }
2009
2010 static void
2011 type_iface_ensure_dflt_vtable_Wm (TypeNode *iface)
2012 {
2013   g_assert (iface->data);
2014
2015   if (!iface->data->iface.dflt_vtable)
2016     {
2017       GTypeInterface *vtable = g_malloc0 (iface->data->iface.vtable_size);
2018       iface->data->iface.dflt_vtable = vtable;
2019       vtable->g_type = NODE_TYPE (iface);
2020       vtable->g_instance_type = 0;
2021       if (iface->data->iface.vtable_init_base ||
2022           iface->data->iface.dflt_init)
2023         {
2024           G_WRITE_UNLOCK (&type_rw_lock);
2025           if (iface->data->iface.vtable_init_base)
2026             iface->data->iface.vtable_init_base (vtable);
2027           if (iface->data->iface.dflt_init)
2028             iface->data->iface.dflt_init (vtable, (gpointer) iface->data->iface.dflt_data);
2029           G_WRITE_LOCK (&type_rw_lock);
2030         }
2031     }
2032 }
2033
2034
2035 /* This is called to allocate and do the first part of initializing
2036  * the interface vtable; type_iface_vtable_iface_init_Wm() does the remainder.
2037  *
2038  * A FALSE return indicates that we didn't find an init function for
2039  * this type/iface pair, so the vtable from the parent type should
2040  * be used. Note that the write lock is not modified upon a FALSE
2041  * return.
2042  */
2043 static gboolean
2044 type_iface_vtable_base_init_Wm (TypeNode *iface,
2045                                 TypeNode *node)
2046 {
2047   IFaceEntry *entry;
2048   IFaceHolder *iholder;
2049   GTypeInterface *vtable = NULL;
2050   TypeNode *pnode;
2051   
2052   /* type_iface_retrieve_holder_info_Wm() doesn't modify write lock for returning NULL */
2053   iholder = type_iface_retrieve_holder_info_Wm (iface, NODE_TYPE (node), TRUE);
2054   if (!iholder)
2055     return FALSE;       /* we don't modify write lock upon FALSE */
2056
2057   type_iface_ensure_dflt_vtable_Wm (iface);
2058
2059   entry = type_lookup_iface_entry_L (node, iface);
2060
2061   g_assert (iface->data && entry && entry->vtable == NULL && iholder && iholder->info);
2062   
2063   entry->init_state = IFACE_INIT;
2064
2065   pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
2066   if (pnode)    /* want to copy over parent iface contents */
2067     {
2068       IFaceEntry *pentry = type_lookup_iface_entry_L (pnode, iface);
2069       
2070       if (pentry)
2071         vtable = g_memdup (pentry->vtable, iface->data->iface.vtable_size);
2072     }
2073   if (!vtable)
2074     vtable = g_memdup (iface->data->iface.dflt_vtable, iface->data->iface.vtable_size);
2075   entry->vtable = vtable;
2076   vtable->g_type = NODE_TYPE (iface);
2077   vtable->g_instance_type = NODE_TYPE (node);
2078   
2079   if (iface->data->iface.vtable_init_base)
2080     {
2081       G_WRITE_UNLOCK (&type_rw_lock);
2082       iface->data->iface.vtable_init_base (vtable);
2083       G_WRITE_LOCK (&type_rw_lock);
2084     }
2085   return TRUE;  /* initialized the vtable */
2086 }
2087
2088 /* Finishes what type_iface_vtable_base_init_Wm started by
2089  * calling the interface init function.
2090  * this function may only be called for types with their
2091  * own interface holder info, i.e. types for which
2092  * g_type_add_interface*() was called and not children thereof.
2093  */
2094 static void
2095 type_iface_vtable_iface_init_Wm (TypeNode *iface,
2096                                  TypeNode *node)
2097 {
2098   IFaceEntry *entry = type_lookup_iface_entry_L (node, iface);
2099   IFaceHolder *iholder = type_iface_peek_holder_L (iface, NODE_TYPE (node));
2100   GTypeInterface *vtable = NULL;
2101   guint i;
2102   
2103   /* iholder->info should have been filled in by type_iface_vtable_base_init_Wm() */
2104   g_assert (iface->data && entry && iholder && iholder->info);
2105   g_assert (entry->init_state == IFACE_INIT); /* assert prior base_init() */
2106   
2107   entry->init_state = INITIALIZED;
2108       
2109   vtable = entry->vtable;
2110
2111   if (iholder->info->interface_init)
2112     {
2113       G_WRITE_UNLOCK (&type_rw_lock);
2114       if (iholder->info->interface_init)
2115         iholder->info->interface_init (vtable, iholder->info->interface_data);
2116       G_WRITE_LOCK (&type_rw_lock);
2117     }
2118   
2119   for (i = 0; i < static_n_iface_check_funcs; i++)
2120     {
2121       GTypeInterfaceCheckFunc check_func = static_iface_check_funcs[i].check_func;
2122       gpointer check_data = static_iface_check_funcs[i].check_data;
2123
2124       G_WRITE_UNLOCK (&type_rw_lock);
2125       check_func (check_data, (gpointer)vtable);
2126       G_WRITE_LOCK (&type_rw_lock);      
2127     }
2128 }
2129
2130 static gboolean
2131 type_iface_vtable_finalize_Wm (TypeNode       *iface,
2132                                TypeNode       *node,
2133                                GTypeInterface *vtable)
2134 {
2135   IFaceEntry *entry = type_lookup_iface_entry_L (node, iface);
2136   IFaceHolder *iholder;
2137   
2138   /* type_iface_retrieve_holder_info_Wm() doesn't modify write lock for returning NULL */
2139   iholder = type_iface_retrieve_holder_info_Wm (iface, NODE_TYPE (node), FALSE);
2140   if (!iholder)
2141     return FALSE;       /* we don't modify write lock upon FALSE */
2142   
2143   g_assert (entry && entry->vtable == vtable && iholder->info);
2144   
2145   entry->vtable = NULL;
2146   entry->init_state = UNINITIALIZED;
2147   if (iholder->info->interface_finalize || iface->data->iface.vtable_finalize_base)
2148     {
2149       G_WRITE_UNLOCK (&type_rw_lock);
2150       if (iholder->info->interface_finalize)
2151         iholder->info->interface_finalize (vtable, iholder->info->interface_data);
2152       if (iface->data->iface.vtable_finalize_base)
2153         iface->data->iface.vtable_finalize_base (vtable);
2154       G_WRITE_LOCK (&type_rw_lock);
2155     }
2156   vtable->g_type = 0;
2157   vtable->g_instance_type = 0;
2158   g_free (vtable);
2159   
2160   type_iface_blow_holder_info_Wm (iface, NODE_TYPE (node));
2161   
2162   return TRUE;  /* write lock modified */
2163 }
2164
2165 static void
2166 type_class_init_Wm (TypeNode   *node,
2167                     GTypeClass *pclass)
2168 {
2169   GSList *slist, *init_slist = NULL;
2170   GTypeClass *class;
2171   IFaceEntries *entries;
2172   IFaceEntry *entry;
2173   TypeNode *bnode, *pnode;
2174   guint i;
2175   
2176   /* Accessing data->class will work for instantiatable types
2177    * too because ClassData is a subset of InstanceData
2178    */
2179   g_assert (node->is_classed && node->data &&
2180             node->data->class.class_size &&
2181             !node->data->class.class &&
2182             g_atomic_int_get (&node->data->class.init_state) == UNINITIALIZED);
2183   if (node->data->class.class_private_size)
2184     class = g_malloc0 (ALIGN_STRUCT (node->data->class.class_size) + node->data->class.class_private_size);
2185   else
2186     class = g_malloc0 (node->data->class.class_size);
2187   node->data->class.class = class;
2188   g_atomic_int_set (&node->data->class.init_state, BASE_CLASS_INIT);
2189   
2190   if (pclass)
2191     {
2192       TypeNode *pnode = lookup_type_node_I (pclass->g_type);
2193       
2194       memcpy (class, pclass, pnode->data->class.class_size);
2195       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);
2196
2197       if (node->is_instantiatable)
2198         {
2199           /* We need to initialize the private_size here rather than in
2200            * type_data_make_W() since the class init for the parent
2201            * class may have changed pnode->data->instance.private_size.
2202            */
2203           node->data->instance.private_size = pnode->data->instance.private_size;
2204         }
2205     }
2206   class->g_type = NODE_TYPE (node);
2207   
2208   G_WRITE_UNLOCK (&type_rw_lock);
2209   
2210   /* stack all base class initialization functions, so we
2211    * call them in ascending order.
2212    */
2213   for (bnode = node; bnode; bnode = lookup_type_node_I (NODE_PARENT_TYPE (bnode)))
2214     if (bnode->data->class.class_init_base)
2215       init_slist = g_slist_prepend (init_slist, (gpointer) bnode->data->class.class_init_base);
2216   for (slist = init_slist; slist; slist = slist->next)
2217     {
2218       GBaseInitFunc class_init_base = (GBaseInitFunc) slist->data;
2219       
2220       class_init_base (class);
2221     }
2222   g_slist_free (init_slist);
2223   
2224   G_WRITE_LOCK (&type_rw_lock);
2225
2226   g_atomic_int_set (&node->data->class.init_state, BASE_IFACE_INIT);
2227   
2228   /* Before we initialize the class, base initialize all interfaces, either
2229    * from parent, or through our holder info
2230    */
2231   pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
2232
2233   i = 0;
2234   while ((entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node)) != NULL &&
2235           i < IFACE_ENTRIES_N_ENTRIES (entries))
2236     {
2237       entry = &entries->entry[i];
2238       while (i < IFACE_ENTRIES_N_ENTRIES (entries) &&
2239              entry->init_state == IFACE_INIT)
2240         {
2241           entry++;
2242           i++;
2243         }
2244
2245       if (i == IFACE_ENTRIES_N_ENTRIES (entries))
2246         break;
2247
2248       if (!type_iface_vtable_base_init_Wm (lookup_type_node_I (entry->iface_type), node))
2249         {
2250           guint j;
2251           IFaceEntries *pentries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (pnode);
2252           
2253           /* need to get this interface from parent, type_iface_vtable_base_init_Wm()
2254            * doesn't modify write lock upon FALSE, so entry is still valid; 
2255            */
2256           g_assert (pnode != NULL);
2257
2258           if (pentries)
2259             for (j = 0; j < IFACE_ENTRIES_N_ENTRIES (pentries); j++)
2260               {
2261                 IFaceEntry *pentry = &pentries->entry[j];
2262
2263                 if (pentry->iface_type == entry->iface_type)
2264                   {
2265                     entry->vtable = pentry->vtable;
2266                     entry->init_state = INITIALIZED;
2267                     break;
2268                   }
2269               }
2270           g_assert (entry->vtable != NULL);
2271         }
2272
2273       /* If the write lock was released, additional interface entries might
2274        * have been inserted into CLASSED_NODE_IFACES_ENTRIES (node); they'll
2275        * be base-initialized when inserted, so we don't have to worry that
2276        * we might miss them. Uninitialized entries can only be moved higher
2277        * when new ones are inserted.
2278        */
2279       i++;
2280     }
2281   
2282   g_atomic_int_set (&node->data->class.init_state, CLASS_INIT);
2283   
2284   G_WRITE_UNLOCK (&type_rw_lock);
2285
2286   if (node->data->class.class_init)
2287     node->data->class.class_init (class, (gpointer) node->data->class.class_data);
2288   
2289   G_WRITE_LOCK (&type_rw_lock);
2290   
2291   g_atomic_int_set (&node->data->class.init_state, IFACE_INIT);
2292   
2293   /* finish initializing the interfaces through our holder info.
2294    * inherited interfaces are already init_state == INITIALIZED, because
2295    * they either got setup in the above base_init loop, or during
2296    * class_init from within type_add_interface_Wm() for this or
2297    * an ancestor type.
2298    */
2299   i = 0;
2300   while ((entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node)) != NULL)
2301     {
2302       entry = &entries->entry[i];
2303       while (i < IFACE_ENTRIES_N_ENTRIES (entries) &&
2304              entry->init_state == INITIALIZED)
2305         {
2306           entry++;
2307           i++;
2308         }
2309
2310       if (i == IFACE_ENTRIES_N_ENTRIES (entries))
2311         break;
2312
2313       type_iface_vtable_iface_init_Wm (lookup_type_node_I (entry->iface_type), node);
2314       
2315       /* As in the loop above, additional initialized entries might be inserted
2316        * if the write lock is released, but that's harmless because the entries
2317        * we need to initialize only move higher in the list.
2318        */
2319       i++;
2320     }
2321   
2322   g_atomic_int_set (&node->data->class.init_state, INITIALIZED);
2323 }
2324
2325 static void
2326 type_data_finalize_class_ifaces_Wm (TypeNode *node)
2327 {
2328   guint i;
2329   IFaceEntries *entries;
2330
2331   g_assert (node->is_instantiatable && node->data && node->data->class.class && NODE_REFCOUNT (node) == 0);
2332
2333  reiterate:
2334   entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node);
2335   for (i = 0; entries != NULL && i < IFACE_ENTRIES_N_ENTRIES (entries); i++)
2336     {
2337       IFaceEntry *entry = &entries->entry[i];
2338       if (entry->vtable)
2339         {
2340           if (type_iface_vtable_finalize_Wm (lookup_type_node_I (entry->iface_type), node, entry->vtable))
2341             {
2342               /* refetch entries, IFACES_ENTRIES might be modified */
2343               goto reiterate;
2344             }
2345           else
2346             {
2347               /* type_iface_vtable_finalize_Wm() doesn't modify write lock upon FALSE,
2348                * iface vtable came from parent
2349                */
2350               entry->vtable = NULL;
2351               entry->init_state = UNINITIALIZED;
2352             }
2353         }
2354     }
2355 }
2356
2357 static void
2358 type_data_finalize_class_U (TypeNode  *node,
2359                             ClassData *cdata)
2360 {
2361   GTypeClass *class = cdata->class;
2362   TypeNode *bnode;
2363   
2364   g_assert (cdata->class && NODE_REFCOUNT (node) == 0);
2365   
2366   if (cdata->class_finalize)
2367     cdata->class_finalize (class, (gpointer) cdata->class_data);
2368   
2369   /* call all base class destruction functions in descending order
2370    */
2371   if (cdata->class_finalize_base)
2372     cdata->class_finalize_base (class);
2373   for (bnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); bnode; bnode = lookup_type_node_I (NODE_PARENT_TYPE (bnode)))
2374     if (bnode->data->class.class_finalize_base)
2375       bnode->data->class.class_finalize_base (class);
2376   
2377   g_free (cdata->class);
2378 }
2379
2380 static void
2381 type_data_last_unref_Wm (TypeNode *node,
2382                          gboolean  uncached)
2383 {
2384   g_return_if_fail (node != NULL && node->plugin != NULL);
2385   
2386   if (!node->data || NODE_REFCOUNT (node) == 0)
2387     {
2388       g_warning ("cannot drop last reference to unreferenced type '%s'",
2389                  NODE_NAME (node));
2390       return;
2391     }
2392
2393   /* call class cache hooks */
2394   if (node->is_classed && node->data && node->data->class.class && static_n_class_cache_funcs && !uncached)
2395     {
2396       guint i;
2397       
2398       G_WRITE_UNLOCK (&type_rw_lock);
2399       G_READ_LOCK (&type_rw_lock);
2400       for (i = 0; i < static_n_class_cache_funcs; i++)
2401         {
2402           GTypeClassCacheFunc cache_func = static_class_cache_funcs[i].cache_func;
2403           gpointer cache_data = static_class_cache_funcs[i].cache_data;
2404           gboolean need_break;
2405           
2406           G_READ_UNLOCK (&type_rw_lock);
2407           need_break = cache_func (cache_data, node->data->class.class);
2408           G_READ_LOCK (&type_rw_lock);
2409           if (!node->data || NODE_REFCOUNT (node) == 0)
2410             INVALID_RECURSION ("GType class cache function ", cache_func, NODE_NAME (node));
2411           if (need_break)
2412             break;
2413         }
2414       G_READ_UNLOCK (&type_rw_lock);
2415       G_WRITE_LOCK (&type_rw_lock);
2416     }
2417   
2418   /* may have been re-referenced meanwhile */
2419   if (g_atomic_int_dec_and_test ((int *) &node->ref_count))
2420     {
2421       GType ptype = NODE_PARENT_TYPE (node);
2422       TypeData *tdata;
2423       
2424       if (node->is_instantiatable)
2425         {
2426           /* destroy node->data->instance.mem_chunk */
2427         }
2428       
2429       tdata = node->data;
2430       if (node->is_classed && tdata->class.class)
2431         {
2432           if (CLASSED_NODE_IFACES_ENTRIES_LOCKED (node) != NULL)
2433             type_data_finalize_class_ifaces_Wm (node);
2434           node->mutatable_check_cache = FALSE;
2435           node->data = NULL;
2436           G_WRITE_UNLOCK (&type_rw_lock);
2437           type_data_finalize_class_U (node, &tdata->class);
2438           G_WRITE_LOCK (&type_rw_lock);
2439         }
2440       else if (NODE_IS_IFACE (node) && tdata->iface.dflt_vtable)
2441         {
2442           node->mutatable_check_cache = FALSE;
2443           node->data = NULL;
2444           if (tdata->iface.dflt_finalize || tdata->iface.vtable_finalize_base)
2445             {
2446               G_WRITE_UNLOCK (&type_rw_lock);
2447               if (tdata->iface.dflt_finalize)
2448                 tdata->iface.dflt_finalize (tdata->iface.dflt_vtable, (gpointer) tdata->iface.dflt_data);
2449               if (tdata->iface.vtable_finalize_base)
2450                 tdata->iface.vtable_finalize_base (tdata->iface.dflt_vtable);
2451               G_WRITE_LOCK (&type_rw_lock);
2452             }
2453           g_free (tdata->iface.dflt_vtable);
2454         }
2455       else
2456         {
2457           node->mutatable_check_cache = FALSE;
2458           node->data = NULL;
2459         }
2460
2461       /* freeing tdata->common.value_table and its contents is taken care of
2462        * by allocating it in one chunk with tdata
2463        */
2464       g_free (tdata);
2465       
2466       G_WRITE_UNLOCK (&type_rw_lock);
2467       g_type_plugin_unuse (node->plugin);
2468       if (ptype)
2469         type_data_unref_U (lookup_type_node_I (ptype), FALSE);
2470       G_WRITE_LOCK (&type_rw_lock);
2471     }
2472 }
2473
2474 static inline void
2475 type_data_unref_U (TypeNode *node,
2476                    gboolean  uncached)
2477 {
2478   guint current;
2479
2480   do {
2481     current = NODE_REFCOUNT (node);
2482
2483     if (current <= 1)
2484     {
2485       if (!node->plugin)
2486         {
2487           g_warning ("static type '%s' unreferenced too often",
2488                      NODE_NAME (node));
2489           return;
2490         }
2491       else
2492         {
2493           /* This is the last reference of a type from a plugin.  We are
2494            * experimentally disabling support for unloading type
2495            * plugins, so don't allow the last ref to drop.
2496            */
2497           return;
2498         }
2499
2500       g_assert (current > 0);
2501
2502       g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */
2503       G_WRITE_LOCK (&type_rw_lock);
2504       type_data_last_unref_Wm (node, uncached);
2505       G_WRITE_UNLOCK (&type_rw_lock);
2506       g_rec_mutex_unlock (&class_init_rec_mutex);
2507       return;
2508     }
2509   } while (!g_atomic_int_compare_and_exchange ((int *) &node->ref_count, current, current - 1));
2510 }
2511
2512 /**
2513  * g_type_add_class_cache_func: (skip)
2514  * @cache_data: data to be passed to @cache_func
2515  * @cache_func: a #GTypeClassCacheFunc
2516  *
2517  * Adds a #GTypeClassCacheFunc to be called before the reference count of a
2518  * class goes from one to zero. This can be used to prevent premature class
2519  * destruction. All installed #GTypeClassCacheFunc functions will be chained
2520  * until one of them returns %TRUE. The functions have to check the class id
2521  * passed in to figure whether they actually want to cache the class of this
2522  * type, since all classes are routed through the same #GTypeClassCacheFunc
2523  * chain.
2524  */
2525 void
2526 g_type_add_class_cache_func (gpointer            cache_data,
2527                              GTypeClassCacheFunc cache_func)
2528 {
2529   guint i;
2530   
2531   g_return_if_fail (cache_func != NULL);
2532   
2533   G_WRITE_LOCK (&type_rw_lock);
2534   i = static_n_class_cache_funcs++;
2535   static_class_cache_funcs = g_renew (ClassCacheFunc, static_class_cache_funcs, static_n_class_cache_funcs);
2536   static_class_cache_funcs[i].cache_data = cache_data;
2537   static_class_cache_funcs[i].cache_func = cache_func;
2538   G_WRITE_UNLOCK (&type_rw_lock);
2539 }
2540
2541 /**
2542  * g_type_remove_class_cache_func: (skip)
2543  * @cache_data: data that was given when adding @cache_func
2544  * @cache_func: a #GTypeClassCacheFunc
2545  *
2546  * Removes a previously installed #GTypeClassCacheFunc. The cache
2547  * maintained by @cache_func has to be empty when calling
2548  * g_type_remove_class_cache_func() to avoid leaks.
2549  */
2550 void
2551 g_type_remove_class_cache_func (gpointer            cache_data,
2552                                 GTypeClassCacheFunc cache_func)
2553 {
2554   gboolean found_it = FALSE;
2555   guint i;
2556   
2557   g_return_if_fail (cache_func != NULL);
2558   
2559   G_WRITE_LOCK (&type_rw_lock);
2560   for (i = 0; i < static_n_class_cache_funcs; i++)
2561     if (static_class_cache_funcs[i].cache_data == cache_data &&
2562         static_class_cache_funcs[i].cache_func == cache_func)
2563       {
2564         static_n_class_cache_funcs--;
2565         memmove (static_class_cache_funcs + i,
2566                  static_class_cache_funcs + i + 1,
2567                  sizeof (static_class_cache_funcs[0]) * (static_n_class_cache_funcs - i));
2568         static_class_cache_funcs = g_renew (ClassCacheFunc, static_class_cache_funcs, static_n_class_cache_funcs);
2569         found_it = TRUE;
2570         break;
2571       }
2572   G_WRITE_UNLOCK (&type_rw_lock);
2573   
2574   if (!found_it)
2575     g_warning (G_STRLOC ": cannot remove unregistered class cache func %p with data %p",
2576                cache_func, cache_data);
2577 }
2578
2579
2580 /**
2581  * g_type_add_interface_check: (skip)
2582  * @check_data: data to pass to @check_func
2583  * @check_func: function to be called after each interface
2584  *     is initialized
2585  *
2586  * Adds a function to be called after an interface vtable is
2587  * initialized for any class (i.e. after the @interface_init
2588  * member of #GInterfaceInfo has been called).
2589  *
2590  * This function is useful when you want to check an invariant
2591  * that depends on the interfaces of a class. For instance, the
2592  * implementation of #GObject uses this facility to check that an
2593  * object implements all of the properties that are defined on its
2594  * interfaces.
2595  *
2596  * Since: 2.4
2597  */
2598 void
2599 g_type_add_interface_check (gpointer                check_data,
2600                             GTypeInterfaceCheckFunc check_func)
2601 {
2602   guint i;
2603   
2604   g_return_if_fail (check_func != NULL);
2605   
2606   G_WRITE_LOCK (&type_rw_lock);
2607   i = static_n_iface_check_funcs++;
2608   static_iface_check_funcs = g_renew (IFaceCheckFunc, static_iface_check_funcs, static_n_iface_check_funcs);
2609   static_iface_check_funcs[i].check_data = check_data;
2610   static_iface_check_funcs[i].check_func = check_func;
2611   G_WRITE_UNLOCK (&type_rw_lock);
2612 }
2613
2614 /**
2615  * g_type_remove_interface_check: (skip)
2616  * @check_data: callback data passed to g_type_add_interface_check()
2617  * @check_func: callback function passed to g_type_add_interface_check()
2618  *
2619  * Removes an interface check function added with
2620  * g_type_add_interface_check().
2621  *
2622  * Since: 2.4
2623  */
2624 void
2625 g_type_remove_interface_check (gpointer                check_data,
2626                                GTypeInterfaceCheckFunc check_func)
2627 {
2628   gboolean found_it = FALSE;
2629   guint i;
2630   
2631   g_return_if_fail (check_func != NULL);
2632   
2633   G_WRITE_LOCK (&type_rw_lock);
2634   for (i = 0; i < static_n_iface_check_funcs; i++)
2635     if (static_iface_check_funcs[i].check_data == check_data &&
2636         static_iface_check_funcs[i].check_func == check_func)
2637       {
2638         static_n_iface_check_funcs--;
2639         memmove (static_iface_check_funcs + i,
2640                  static_iface_check_funcs + i + 1,
2641                  sizeof (static_iface_check_funcs[0]) * (static_n_iface_check_funcs - i));
2642         static_iface_check_funcs = g_renew (IFaceCheckFunc, static_iface_check_funcs, static_n_iface_check_funcs);
2643         found_it = TRUE;
2644         break;
2645       }
2646   G_WRITE_UNLOCK (&type_rw_lock);
2647   
2648   if (!found_it)
2649     g_warning (G_STRLOC ": cannot remove unregistered class check func %p with data %p",
2650                check_func, check_data);
2651 }
2652
2653 /* --- type registration --- */
2654 /**
2655  * g_type_register_fundamental:
2656  * @type_id: a predefined type identifier
2657  * @type_name: 0-terminated string used as the name of the new type
2658  * @info: #GTypeInfo structure for this type
2659  * @finfo: #GTypeFundamentalInfo structure for this type
2660  * @flags: bitwise combination of #GTypeFlags values
2661  *
2662  * Registers @type_id as the predefined identifier and @type_name as the
2663  * name of a fundamental type. If @type_id is already registered, or a
2664  * type named @type_name is already registered, the behaviour is undefined.
2665  * The type system uses the information contained in the #GTypeInfo structure
2666  * pointed to by @info and the #GTypeFundamentalInfo structure pointed to by
2667  * @finfo to manage the type and its instances. The value of @flags determines
2668  * additional characteristics of the fundamental type.
2669  *
2670  * Returns: the predefined type identifier
2671  */
2672 GType
2673 g_type_register_fundamental (GType                       type_id,
2674                              const gchar                *type_name,
2675                              const GTypeInfo            *info,
2676                              const GTypeFundamentalInfo *finfo,
2677                              GTypeFlags                  flags)
2678 {
2679   TypeNode *node;
2680   
2681   g_assert_type_system_initialized ();
2682   g_return_val_if_fail (type_id > 0, 0);
2683   g_return_val_if_fail (type_name != NULL, 0);
2684   g_return_val_if_fail (info != NULL, 0);
2685   g_return_val_if_fail (finfo != NULL, 0);
2686   
2687   if (!check_type_name_I (type_name))
2688     return 0;
2689   if ((type_id & TYPE_ID_MASK) ||
2690       type_id > G_TYPE_FUNDAMENTAL_MAX)
2691     {
2692       g_warning ("attempt to register fundamental type '%s' with invalid type id (%" G_GSIZE_FORMAT ")",
2693                  type_name,
2694                  type_id);
2695       return 0;
2696     }
2697   if ((finfo->type_flags & G_TYPE_FLAG_INSTANTIATABLE) &&
2698       !(finfo->type_flags & G_TYPE_FLAG_CLASSED))
2699     {
2700       g_warning ("cannot register instantiatable fundamental type '%s' as non-classed",
2701                  type_name);
2702       return 0;
2703     }
2704   if (lookup_type_node_I (type_id))
2705     {
2706       g_warning ("cannot register existing fundamental type '%s' (as '%s')",
2707                  type_descriptive_name_I (type_id),
2708                  type_name);
2709       return 0;
2710     }
2711   
2712   G_WRITE_LOCK (&type_rw_lock);
2713   node = type_node_fundamental_new_W (type_id, type_name, finfo->type_flags);
2714   type_add_flags_W (node, flags);
2715   
2716   if (check_type_info_I (NULL, NODE_FUNDAMENTAL_TYPE (node), type_name, info))
2717     type_data_make_W (node, info,
2718                       check_value_table_I (type_name, info->value_table) ? info->value_table : NULL);
2719   G_WRITE_UNLOCK (&type_rw_lock);
2720   
2721   return NODE_TYPE (node);
2722 }
2723
2724 /**
2725  * g_type_register_static_simple: (skip)
2726  * @parent_type: type from which this type will be derived
2727  * @type_name: 0-terminated string used as the name of the new type
2728  * @class_size: size of the class structure (see #GTypeInfo)
2729  * @class_init: location of the class initialization function (see #GTypeInfo)
2730  * @instance_size: size of the instance structure (see #GTypeInfo)
2731  * @instance_init: location of the instance initialization function (see #GTypeInfo)
2732  * @flags: bitwise combination of #GTypeFlags values
2733  *
2734  * Registers @type_name as the name of a new static type derived from
2735  * @parent_type.  The value of @flags determines the nature (e.g.
2736  * abstract or not) of the type. It works by filling a #GTypeInfo
2737  * struct and calling g_type_register_static().
2738  *
2739  * Since: 2.12
2740  *
2741  * Returns: the new type identifier
2742  */
2743 GType
2744 g_type_register_static_simple (GType             parent_type,
2745                                const gchar      *type_name,
2746                                guint             class_size,
2747                                GClassInitFunc    class_init,
2748                                guint             instance_size,
2749                                GInstanceInitFunc instance_init,
2750                                GTypeFlags        flags)
2751 {
2752   GTypeInfo info;
2753
2754   /* Instances are not allowed to be larger than this. If you have a big
2755    * fixed-length array or something, point to it instead.
2756    */
2757   g_return_val_if_fail (class_size <= G_MAXUINT16, G_TYPE_INVALID);
2758   g_return_val_if_fail (instance_size <= G_MAXUINT16, G_TYPE_INVALID);
2759
2760   info.class_size = class_size;
2761   info.base_init = NULL;
2762   info.base_finalize = NULL;
2763   info.class_init = class_init;
2764   info.class_finalize = NULL;
2765   info.class_data = NULL;
2766   info.instance_size = instance_size;
2767   info.n_preallocs = 0;
2768   info.instance_init = instance_init;
2769   info.value_table = NULL;
2770
2771   return g_type_register_static (parent_type, type_name, &info, flags);
2772 }
2773
2774 /**
2775  * g_type_register_static:
2776  * @parent_type: type from which this type will be derived
2777  * @type_name: 0-terminated string used as the name of the new type
2778  * @info: #GTypeInfo structure for this type
2779  * @flags: bitwise combination of #GTypeFlags values
2780  *
2781  * Registers @type_name as the name of a new static type derived from
2782  * @parent_type. The type system uses the information contained in the
2783  * #GTypeInfo structure pointed to by @info to manage the type and its
2784  * instances (if not abstract). The value of @flags determines the nature
2785  * (e.g. abstract or not) of the type.
2786  *
2787  * Returns: the new type identifier
2788  */
2789 GType
2790 g_type_register_static (GType            parent_type,
2791                         const gchar     *type_name,
2792                         const GTypeInfo *info,
2793                         GTypeFlags       flags)
2794 {
2795   TypeNode *pnode, *node;
2796   GType type = 0;
2797   
2798   g_assert_type_system_initialized ();
2799   g_return_val_if_fail (parent_type > 0, 0);
2800   g_return_val_if_fail (type_name != NULL, 0);
2801   g_return_val_if_fail (info != NULL, 0);
2802   
2803   if (!check_type_name_I (type_name) ||
2804       !check_derivation_I (parent_type, type_name))
2805     return 0;
2806   if (info->class_finalize)
2807     {
2808       g_warning ("class finalizer specified for static type '%s'",
2809                  type_name);
2810       return 0;
2811     }
2812   
2813   pnode = lookup_type_node_I (parent_type);
2814   G_WRITE_LOCK (&type_rw_lock);
2815   type_data_ref_Wm (pnode);
2816   if (check_type_info_I (pnode, NODE_FUNDAMENTAL_TYPE (pnode), type_name, info))
2817     {
2818       node = type_node_new_W (pnode, type_name, NULL);
2819       type_add_flags_W (node, flags);
2820       type = NODE_TYPE (node);
2821       type_data_make_W (node, info,
2822                         check_value_table_I (type_name, info->value_table) ? info->value_table : NULL);
2823     }
2824   G_WRITE_UNLOCK (&type_rw_lock);
2825   
2826   return type;
2827 }
2828
2829 /**
2830  * g_type_register_dynamic:
2831  * @parent_type: type from which this type will be derived
2832  * @type_name: 0-terminated string used as the name of the new type
2833  * @plugin: #GTypePlugin structure to retrieve the #GTypeInfo from
2834  * @flags: bitwise combination of #GTypeFlags values
2835  *
2836  * Registers @type_name as the name of a new dynamic type derived from
2837  * @parent_type.  The type system uses the information contained in the
2838  * #GTypePlugin structure pointed to by @plugin to manage the type and its
2839  * instances (if not abstract).  The value of @flags determines the nature
2840  * (e.g. abstract or not) of the type.
2841  *
2842  * Returns: the new type identifier or #G_TYPE_INVALID if registration failed
2843  */
2844 GType
2845 g_type_register_dynamic (GType        parent_type,
2846                          const gchar *type_name,
2847                          GTypePlugin *plugin,
2848                          GTypeFlags   flags)
2849 {
2850   TypeNode *pnode, *node;
2851   GType type;
2852   
2853   g_assert_type_system_initialized ();
2854   g_return_val_if_fail (parent_type > 0, 0);
2855   g_return_val_if_fail (type_name != NULL, 0);
2856   g_return_val_if_fail (plugin != NULL, 0);
2857   
2858   if (!check_type_name_I (type_name) ||
2859       !check_derivation_I (parent_type, type_name) ||
2860       !check_plugin_U (plugin, TRUE, FALSE, type_name))
2861     return 0;
2862   
2863   G_WRITE_LOCK (&type_rw_lock);
2864   pnode = lookup_type_node_I (parent_type);
2865   node = type_node_new_W (pnode, type_name, plugin);
2866   type_add_flags_W (node, flags);
2867   type = NODE_TYPE (node);
2868   G_WRITE_UNLOCK (&type_rw_lock);
2869   
2870   return type;
2871 }
2872
2873 /**
2874  * g_type_add_interface_static:
2875  * @instance_type: #GType value of an instantiatable type
2876  * @interface_type: #GType value of an interface type
2877  * @info: #GInterfaceInfo structure for this
2878  *        (@instance_type, @interface_type) combination
2879  *
2880  * Adds @interface_type to the static @instance_type.
2881  * The information contained in the #GInterfaceInfo structure
2882  * pointed to by @info is used to manage the relationship.
2883  */
2884 void
2885 g_type_add_interface_static (GType                 instance_type,
2886                              GType                 interface_type,
2887                              const GInterfaceInfo *info)
2888 {
2889   /* G_TYPE_IS_INSTANTIATABLE() is an external call: _U */
2890   g_return_if_fail (G_TYPE_IS_INSTANTIATABLE (instance_type));
2891   g_return_if_fail (g_type_parent (interface_type) == G_TYPE_INTERFACE);
2892
2893   /* we only need to lock class_init_rec_mutex if instance_type already has its
2894    * class initialized, however this function is rarely enough called to take
2895    * the simple route and always acquire class_init_rec_mutex.
2896    */
2897   g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */
2898   G_WRITE_LOCK (&type_rw_lock);
2899   if (check_add_interface_L (instance_type, interface_type))
2900     {
2901       TypeNode *node = lookup_type_node_I (instance_type);
2902       TypeNode *iface = lookup_type_node_I (interface_type);
2903       if (check_interface_info_I (iface, NODE_TYPE (node), info))
2904         type_add_interface_Wm (node, iface, info, NULL);
2905     }
2906   G_WRITE_UNLOCK (&type_rw_lock);
2907   g_rec_mutex_unlock (&class_init_rec_mutex);
2908 }
2909
2910 /**
2911  * g_type_add_interface_dynamic:
2912  * @instance_type: #GType value of an instantiatable type
2913  * @interface_type: #GType value of an interface type
2914  * @plugin: #GTypePlugin structure to retrieve the #GInterfaceInfo from
2915  *
2916  * Adds @interface_type to the dynamic @instance_type. The information
2917  * contained in the #GTypePlugin structure pointed to by @plugin
2918  * is used to manage the relationship.
2919  */
2920 void
2921 g_type_add_interface_dynamic (GType        instance_type,
2922                               GType        interface_type,
2923                               GTypePlugin *plugin)
2924 {
2925   TypeNode *node;
2926   /* G_TYPE_IS_INSTANTIATABLE() is an external call: _U */
2927   g_return_if_fail (G_TYPE_IS_INSTANTIATABLE (instance_type));
2928   g_return_if_fail (g_type_parent (interface_type) == G_TYPE_INTERFACE);
2929
2930   node = lookup_type_node_I (instance_type);
2931   if (!check_plugin_U (plugin, FALSE, TRUE, NODE_NAME (node)))
2932     return;
2933
2934   /* see comment in g_type_add_interface_static() about class_init_rec_mutex */
2935   g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */
2936   G_WRITE_LOCK (&type_rw_lock);
2937   if (check_add_interface_L (instance_type, interface_type))
2938     {
2939       TypeNode *iface = lookup_type_node_I (interface_type);
2940       type_add_interface_Wm (node, iface, NULL, plugin);
2941     }
2942   G_WRITE_UNLOCK (&type_rw_lock);
2943   g_rec_mutex_unlock (&class_init_rec_mutex);
2944 }
2945
2946
2947 /* --- public API functions --- */
2948 /**
2949  * g_type_class_ref:
2950  * @type: type ID of a classed type
2951  *
2952  * Increments the reference count of the class structure belonging to
2953  * @type. This function will demand-create the class if it doesn't
2954  * exist already.
2955  *
2956  * Returns: (type GObject.TypeClass) (transfer none): the #GTypeClass
2957  *     structure for the given type ID
2958  */
2959 gpointer
2960 g_type_class_ref (GType type)
2961 {
2962   TypeNode *node;
2963   GType ptype;
2964   gboolean holds_ref;
2965   GTypeClass *pclass;
2966
2967   /* optimize for common code path */
2968   node = lookup_type_node_I (type);
2969   if (!node || !node->is_classed)
2970     {
2971       g_warning ("cannot retrieve class for invalid (unclassed) type '%s'",
2972                  type_descriptive_name_I (type));
2973       return NULL;
2974     }
2975
2976   if (G_LIKELY (type_data_ref_U (node)))
2977     {
2978       if (G_LIKELY (g_atomic_int_get (&node->data->class.init_state) == INITIALIZED))
2979         return node->data->class.class;
2980       holds_ref = TRUE;
2981     }
2982   else
2983     holds_ref = FALSE;
2984   
2985   /* here, we either have node->data->class.class == NULL, or a recursive
2986    * call to g_type_class_ref() with a partly initialized class, or
2987    * node->data->class.init_state == INITIALIZED, because any
2988    * concurrently running initialization was guarded by class_init_rec_mutex.
2989    */
2990   g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */
2991
2992   /* we need an initialized parent class for initializing derived classes */
2993   ptype = NODE_PARENT_TYPE (node);
2994   pclass = ptype ? g_type_class_ref (ptype) : NULL;
2995
2996   G_WRITE_LOCK (&type_rw_lock);
2997
2998   if (!holds_ref)
2999     type_data_ref_Wm (node);
3000
3001   if (!node->data->class.class) /* class uninitialized */
3002     type_class_init_Wm (node, pclass);
3003
3004   G_WRITE_UNLOCK (&type_rw_lock);
3005
3006   if (pclass)
3007     g_type_class_unref (pclass);
3008
3009   g_rec_mutex_unlock (&class_init_rec_mutex);
3010
3011   return node->data->class.class;
3012 }
3013
3014 /**
3015  * g_type_class_unref:
3016  * @g_class: (type GObject.TypeClass): a #GTypeClass structure to unref
3017  *
3018  * Decrements the reference count of the class structure being passed in.
3019  * Once the last reference count of a class has been released, classes
3020  * may be finalized by the type system, so further dereferencing of a
3021  * class pointer after g_type_class_unref() are invalid.
3022  */
3023 void
3024 g_type_class_unref (gpointer g_class)
3025 {
3026   TypeNode *node;
3027   GTypeClass *class = g_class;
3028   
3029   g_return_if_fail (g_class != NULL);
3030   
3031   node = lookup_type_node_I (class->g_type);
3032   if (node && node->is_classed && NODE_REFCOUNT (node))
3033     type_data_unref_U (node, FALSE);
3034   else
3035     g_warning ("cannot unreference class of invalid (unclassed) type '%s'",
3036                type_descriptive_name_I (class->g_type));
3037 }
3038
3039 /**
3040  * g_type_class_unref_uncached: (skip)
3041  * @g_class: (type GObject.TypeClass): a #GTypeClass structure to unref
3042  *
3043  * A variant of g_type_class_unref() for use in #GTypeClassCacheFunc
3044  * implementations. It unreferences a class without consulting the chain
3045  * of #GTypeClassCacheFuncs, avoiding the recursion which would occur
3046  * otherwise.
3047  */
3048 void
3049 g_type_class_unref_uncached (gpointer g_class)
3050 {
3051   TypeNode *node;
3052   GTypeClass *class = g_class;
3053   
3054   g_return_if_fail (g_class != NULL);
3055   
3056   node = lookup_type_node_I (class->g_type);
3057   if (node && node->is_classed && NODE_REFCOUNT (node))
3058     type_data_unref_U (node, TRUE);
3059   else
3060     g_warning ("cannot unreference class of invalid (unclassed) type '%s'",
3061                type_descriptive_name_I (class->g_type));
3062 }
3063
3064 /**
3065  * g_type_class_peek:
3066  * @type: type ID of a classed type
3067  *
3068  * This function is essentially the same as g_type_class_ref(),
3069  * except that the classes reference count isn't incremented.
3070  * As a consequence, this function may return %NULL if the class
3071  * of the type passed in does not currently exist (hasn't been
3072  * referenced before).
3073  *
3074  * Returns: (type GObject.TypeClass) (transfer none): the #GTypeClass
3075  *     structure for the given type ID or %NULL if the class does not
3076  *     currently exist
3077  */
3078 gpointer
3079 g_type_class_peek (GType type)
3080 {
3081   TypeNode *node;
3082   gpointer class;
3083   
3084   node = lookup_type_node_I (type);
3085   if (node && node->is_classed && NODE_REFCOUNT (node) &&
3086       g_atomic_int_get (&node->data->class.init_state) == INITIALIZED)
3087     /* ref_count _may_ be 0 */
3088     class = node->data->class.class;
3089   else
3090     class = NULL;
3091   
3092   return class;
3093 }
3094
3095 /**
3096  * g_type_class_peek_static:
3097  * @type: type ID of a classed type
3098  *
3099  * A more efficient version of g_type_class_peek() which works only for
3100  * static types.
3101  * 
3102  * Returns: (type GObject.TypeClass) (transfer none): the #GTypeClass
3103  *     structure for the given type ID or %NULL if the class does not
3104  *     currently exist or is dynamically loaded
3105  *
3106  * Since: 2.4
3107  */
3108 gpointer
3109 g_type_class_peek_static (GType type)
3110 {
3111   TypeNode *node;
3112   gpointer class;
3113   
3114   node = lookup_type_node_I (type);
3115   if (node && node->is_classed && NODE_REFCOUNT (node) &&
3116       /* peek only static types: */ node->plugin == NULL &&
3117       g_atomic_int_get (&node->data->class.init_state) == INITIALIZED)
3118     /* ref_count _may_ be 0 */
3119     class = node->data->class.class;
3120   else
3121     class = NULL;
3122   
3123   return class;
3124 }
3125
3126 /**
3127  * g_type_class_peek_parent:
3128  * @g_class: (type GObject.TypeClass): the #GTypeClass structure to
3129  *     retrieve the parent class for
3130  *
3131  * This is a convenience function often needed in class initializers.
3132  * It returns the class structure of the immediate parent type of the
3133  * class passed in.  Since derived classes hold a reference count on
3134  * their parent classes as long as they are instantiated, the returned
3135  * class will always exist.
3136  *
3137  * This function is essentially equivalent to:
3138  * g_type_class_peek (g_type_parent (G_TYPE_FROM_CLASS (g_class)))
3139  *
3140  * Returns: (type GObject.TypeClass) (transfer none): the parent class
3141  *     of @g_class
3142  */
3143 gpointer
3144 g_type_class_peek_parent (gpointer g_class)
3145 {
3146   TypeNode *node;
3147   gpointer class = NULL;
3148   
3149   g_return_val_if_fail (g_class != NULL, NULL);
3150   
3151   node = lookup_type_node_I (G_TYPE_FROM_CLASS (g_class));
3152   /* We used to acquire a read lock here. That is not necessary, since 
3153    * parent->data->class.class is constant as long as the derived class
3154    * exists. 
3155    */
3156   if (node && node->is_classed && node->data && NODE_PARENT_TYPE (node))
3157     {
3158       node = lookup_type_node_I (NODE_PARENT_TYPE (node));
3159       class = node->data->class.class;
3160     }
3161   else if (NODE_PARENT_TYPE (node))
3162     g_warning (G_STRLOC ": invalid class pointer '%p'", g_class);
3163   
3164   return class;
3165 }
3166
3167 /**
3168  * g_type_interface_peek:
3169  * @instance_class: (type GObject.TypeClass): a #GTypeClass structure
3170  * @iface_type: an interface ID which this class conforms to
3171  *
3172  * Returns the #GTypeInterface structure of an interface to which the
3173  * passed in class conforms.
3174  *
3175  * Returns: (type GObject.TypeInterface) (transfer none): the #GTypeInterface
3176  *     structure of @iface_type if implemented by @instance_class, %NULL
3177  *     otherwise
3178  */
3179 gpointer
3180 g_type_interface_peek (gpointer instance_class,
3181                        GType    iface_type)
3182 {
3183   TypeNode *node;
3184   TypeNode *iface;
3185   gpointer vtable = NULL;
3186   GTypeClass *class = instance_class;
3187   
3188   g_return_val_if_fail (instance_class != NULL, NULL);
3189   
3190   node = lookup_type_node_I (class->g_type);
3191   iface = lookup_type_node_I (iface_type);
3192   if (node && node->is_instantiatable && iface)
3193     type_lookup_iface_vtable_I (node, iface, &vtable);
3194   else
3195     g_warning (G_STRLOC ": invalid class pointer '%p'", class);
3196   
3197   return vtable;
3198 }
3199
3200 /**
3201  * g_type_interface_peek_parent:
3202  * @g_iface: (type GObject.TypeInterface): a #GTypeInterface structure
3203  *
3204  * Returns the corresponding #GTypeInterface structure of the parent type
3205  * of the instance type to which @g_iface belongs. This is useful when
3206  * deriving the implementation of an interface from the parent type and
3207  * then possibly overriding some methods.
3208  *
3209  * Returns: (transfer none) (type GObject.TypeInterface): the
3210  *     corresponding #GTypeInterface structure of the parent type of the
3211  *     instance type to which @g_iface belongs, or %NULL if the parent
3212  *     type doesn't conform to the interface
3213  */
3214 gpointer
3215 g_type_interface_peek_parent (gpointer g_iface)
3216 {
3217   TypeNode *node;
3218   TypeNode *iface;
3219   gpointer vtable = NULL;
3220   GTypeInterface *iface_class = g_iface;
3221   
3222   g_return_val_if_fail (g_iface != NULL, NULL);
3223   
3224   iface = lookup_type_node_I (iface_class->g_type);
3225   node = lookup_type_node_I (iface_class->g_instance_type);
3226   if (node)
3227     node = lookup_type_node_I (NODE_PARENT_TYPE (node));
3228   if (node && node->is_instantiatable && iface)
3229     type_lookup_iface_vtable_I (node, iface, &vtable);
3230   else if (node)
3231     g_warning (G_STRLOC ": invalid interface pointer '%p'", g_iface);
3232   
3233   return vtable;
3234 }
3235
3236 /**
3237  * g_type_default_interface_ref:
3238  * @g_type: an interface type
3239  *
3240  * Increments the reference count for the interface type @g_type,
3241  * and returns the default interface vtable for the type.
3242  *
3243  * If the type is not currently in use, then the default vtable
3244  * for the type will be created and initialized by calling
3245  * the base interface init and default vtable init functions for
3246  * the type (the @base_init and @class_init members of #GTypeInfo).
3247  * Calling g_type_default_interface_ref() is useful when you
3248  * want to make sure that signals and properties for an interface
3249  * have been installed.
3250  *
3251  * Since: 2.4
3252  *
3253  * Returns: (type GObject.TypeInterface) (transfer none): the default
3254  *     vtable for the interface; call g_type_default_interface_unref()
3255  *     when you are done using the interface.
3256  */
3257 gpointer
3258 g_type_default_interface_ref (GType g_type)
3259 {
3260   TypeNode *node;
3261   gpointer dflt_vtable;
3262
3263   G_WRITE_LOCK (&type_rw_lock);
3264
3265   node = lookup_type_node_I (g_type);
3266   if (!node || !NODE_IS_IFACE (node) ||
3267       (node->data && NODE_REFCOUNT (node) == 0))
3268     {
3269       G_WRITE_UNLOCK (&type_rw_lock);
3270       g_warning ("cannot retrieve default vtable for invalid or non-interface type '%s'",
3271                  type_descriptive_name_I (g_type));
3272       return NULL;
3273     }
3274
3275   if (!node->data || !node->data->iface.dflt_vtable)
3276     {
3277       G_WRITE_UNLOCK (&type_rw_lock);
3278       g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */
3279       G_WRITE_LOCK (&type_rw_lock);
3280       node = lookup_type_node_I (g_type);
3281       type_data_ref_Wm (node);
3282       type_iface_ensure_dflt_vtable_Wm (node);
3283       g_rec_mutex_unlock (&class_init_rec_mutex);
3284     }
3285   else
3286     type_data_ref_Wm (node); /* ref_count >= 1 already */
3287
3288   dflt_vtable = node->data->iface.dflt_vtable;
3289   G_WRITE_UNLOCK (&type_rw_lock);
3290
3291   return dflt_vtable;
3292 }
3293
3294 /**
3295  * g_type_default_interface_peek:
3296  * @g_type: an interface type
3297  *
3298  * If the interface type @g_type is currently in use, returns its
3299  * default interface vtable.
3300  *
3301  * Since: 2.4
3302  *
3303  * Returns: (type GObject.TypeInterface) (transfer none): the default
3304  *     vtable for the interface, or %NULL if the type is not currently
3305  *     in use
3306  */
3307 gpointer
3308 g_type_default_interface_peek (GType g_type)
3309 {
3310   TypeNode *node;
3311   gpointer vtable;
3312   
3313   node = lookup_type_node_I (g_type);
3314   if (node && NODE_IS_IFACE (node) && NODE_REFCOUNT (node))
3315     vtable = node->data->iface.dflt_vtable;
3316   else
3317     vtable = NULL;
3318   
3319   return vtable;
3320 }
3321
3322 /**
3323  * g_type_default_interface_unref:
3324  * @g_iface: (type GObject.TypeInterface): the default vtable
3325  *     structure for an interface, as returned by g_type_default_interface_ref()
3326  *
3327  * Decrements the reference count for the type corresponding to the
3328  * interface default vtable @g_iface. If the type is dynamic, then
3329  * when no one is using the interface and all references have
3330  * been released, the finalize function for the interface's default
3331  * vtable (the @class_finalize member of #GTypeInfo) will be called.
3332  *
3333  * Since: 2.4
3334  */
3335 void
3336 g_type_default_interface_unref (gpointer g_iface)
3337 {
3338   TypeNode *node;
3339   GTypeInterface *vtable = g_iface;
3340   
3341   g_return_if_fail (g_iface != NULL);
3342   
3343   node = lookup_type_node_I (vtable->g_type);
3344   if (node && NODE_IS_IFACE (node))
3345     type_data_unref_U (node, FALSE);
3346   else
3347     g_warning ("cannot unreference invalid interface default vtable for '%s'",
3348                type_descriptive_name_I (vtable->g_type));
3349 }
3350
3351 /**
3352  * g_type_name:
3353  * @type: type to return name for
3354  *
3355  * Get the unique name that is assigned to a type ID.  Note that this
3356  * function (like all other GType API) cannot cope with invalid type
3357  * IDs. %G_TYPE_INVALID may be passed to this function, as may be any
3358  * other validly registered type ID, but randomized type IDs should
3359  * not be passed in and will most likely lead to a crash.
3360  *
3361  * Returns: static type name or %NULL
3362  */
3363 const gchar *
3364 g_type_name (GType type)
3365 {
3366   TypeNode *node;
3367   
3368   g_assert_type_system_initialized ();
3369   
3370   node = lookup_type_node_I (type);
3371   
3372   return node ? NODE_NAME (node) : NULL;
3373 }
3374
3375 /**
3376  * g_type_qname:
3377  * @type: type to return quark of type name for
3378  *
3379  * Get the corresponding quark of the type IDs name.
3380  *
3381  * Returns: the type names quark or 0
3382  */
3383 GQuark
3384 g_type_qname (GType type)
3385 {
3386   TypeNode *node;
3387   
3388   node = lookup_type_node_I (type);
3389   
3390   return node ? node->qname : 0;
3391 }
3392
3393 /**
3394  * g_type_from_name:
3395  * @name: type name to look up
3396  *
3397  * Look up the type ID from a given type name, returning 0 if no type
3398  * has been registered under this name (this is the preferred method
3399  * to find out by name whether a specific type has been registered
3400  * yet).
3401  *
3402  * Returns: corresponding type ID or 0
3403  */
3404 GType
3405 g_type_from_name (const gchar *name)
3406 {
3407   GType type = 0;
3408   
3409   g_return_val_if_fail (name != NULL, 0);
3410   
3411   G_READ_LOCK (&type_rw_lock);
3412   type = (GType) g_hash_table_lookup (static_type_nodes_ht, name);
3413   G_READ_UNLOCK (&type_rw_lock);
3414   
3415   return type;
3416 }
3417
3418 /**
3419  * g_type_parent:
3420  * @type: the derived type
3421  *
3422  * Return the direct parent type of the passed in type. If the passed
3423  * in type has no parent, i.e. is a fundamental type, 0 is returned.
3424  *
3425  * Returns: the parent type
3426  */
3427 GType
3428 g_type_parent (GType type)
3429 {
3430   TypeNode *node;
3431   
3432   node = lookup_type_node_I (type);
3433   
3434   return node ? NODE_PARENT_TYPE (node) : 0;
3435 }
3436
3437 /**
3438  * g_type_depth:
3439  * @type: a #GType
3440  *
3441  * Returns the length of the ancestry of the passed in type. This
3442  * includes the type itself, so that e.g. a fundamental type has depth 1.
3443  *
3444  * Returns: the depth of @type
3445  */
3446 guint
3447 g_type_depth (GType type)
3448 {
3449   TypeNode *node;
3450   
3451   node = lookup_type_node_I (type);
3452   
3453   return node ? node->n_supers + 1 : 0;
3454 }
3455
3456 /**
3457  * g_type_next_base:
3458  * @leaf_type: descendant of @root_type and the type to be returned
3459  * @root_type: immediate parent of the returned type
3460  *
3461  * Given a @leaf_type and a @root_type which is contained in its
3462  * ancestry, return the type that @root_type is the immediate parent
3463  * of. In other words, this function determines the type that is
3464  * derived directly from @root_type which is also a base class of
3465  * @leaf_type.  Given a root type and a leaf type, this function can
3466  * be used to determine the types and order in which the leaf type is
3467  * descended from the root type.
3468  *
3469  * Returns: immediate child of @root_type and ancestor of @leaf_type
3470  */
3471 GType
3472 g_type_next_base (GType type,
3473                   GType base_type)
3474 {
3475   GType atype = 0;
3476   TypeNode *node;
3477   
3478   node = lookup_type_node_I (type);
3479   if (node)
3480     {
3481       TypeNode *base_node = lookup_type_node_I (base_type);
3482       
3483       if (base_node && base_node->n_supers < node->n_supers)
3484         {
3485           guint n = node->n_supers - base_node->n_supers;
3486           
3487           if (node->supers[n] == base_type)
3488             atype = node->supers[n - 1];
3489         }
3490     }
3491   
3492   return atype;
3493 }
3494
3495 static inline gboolean
3496 type_node_check_conformities_UorL (TypeNode *node,
3497                                    TypeNode *iface_node,
3498                                    /*        support_inheritance */
3499                                    gboolean  support_interfaces,
3500                                    gboolean  support_prerequisites,
3501                                    gboolean  have_lock)
3502 {
3503   gboolean match;
3504
3505   if (/* support_inheritance && */
3506       NODE_IS_ANCESTOR (iface_node, node))
3507     return TRUE;
3508
3509   support_interfaces = support_interfaces && node->is_instantiatable && NODE_IS_IFACE (iface_node);
3510   support_prerequisites = support_prerequisites && NODE_IS_IFACE (node);
3511   match = FALSE;
3512   if (support_interfaces)
3513     {
3514       if (have_lock)
3515         {
3516           if (type_lookup_iface_entry_L (node, iface_node))
3517             match = TRUE;
3518         }
3519       else
3520         {
3521           if (type_lookup_iface_vtable_I (node, iface_node, NULL))
3522             match = TRUE;
3523         }
3524     }
3525   if (!match &&
3526       support_prerequisites)
3527     {
3528       if (!have_lock)
3529         G_READ_LOCK (&type_rw_lock);
3530       if (support_prerequisites && type_lookup_prerequisite_L (node, NODE_TYPE (iface_node)))
3531         match = TRUE;
3532       if (!have_lock)
3533         G_READ_UNLOCK (&type_rw_lock);
3534     }
3535   return match;
3536 }
3537
3538 static gboolean
3539 type_node_is_a_L (TypeNode *node,
3540                   TypeNode *iface_node)
3541 {
3542   return type_node_check_conformities_UorL (node, iface_node, TRUE, TRUE, TRUE);
3543 }
3544
3545 static inline gboolean
3546 type_node_conforms_to_U (TypeNode *node,
3547                          TypeNode *iface_node,
3548                          gboolean  support_interfaces,
3549                          gboolean  support_prerequisites)
3550 {
3551   return type_node_check_conformities_UorL (node, iface_node, support_interfaces, support_prerequisites, FALSE);
3552 }
3553
3554 /**
3555  * g_type_is_a:
3556  * @type: type to check ancestry for
3557  * @is_a_type: possible ancestor of @type or interface that @type
3558  *     could conform to
3559  *
3560  * If @is_a_type is a derivable type, check whether @type is a
3561  * descendant of @is_a_type. If @is_a_type is an interface, check
3562  * whether @type conforms to it.
3563  *
3564  * Returns: %TRUE if @type is a @is_a_type
3565  */
3566 gboolean
3567 g_type_is_a (GType type,
3568              GType iface_type)
3569 {
3570   TypeNode *node, *iface_node;
3571   gboolean is_a;
3572
3573   if (type == iface_type)
3574     return TRUE;
3575   
3576   node = lookup_type_node_I (type);
3577   iface_node = lookup_type_node_I (iface_type);
3578   is_a = node && iface_node && type_node_conforms_to_U (node, iface_node, TRUE, TRUE);
3579   
3580   return is_a;
3581 }
3582
3583 /**
3584  * g_type_children:
3585  * @type: the parent type
3586  * @n_children: (out) (optional): location to store the length of
3587  *     the returned array, or %NULL
3588  *
3589  * Return a newly allocated and 0-terminated array of type IDs, listing
3590  * the child types of @type.
3591  *
3592  * Returns: (array length=n_children) (transfer full): Newly allocated
3593  *     and 0-terminated array of child types, free with g_free()
3594  */
3595 GType*
3596 g_type_children (GType  type,
3597                  guint *n_children)
3598 {
3599   TypeNode *node;
3600   
3601   node = lookup_type_node_I (type);
3602   if (node)
3603     {
3604       GType *children;
3605       
3606       G_READ_LOCK (&type_rw_lock);      /* ->children is relocatable */
3607       children = g_new (GType, node->n_children + 1);
3608       if (node->n_children != 0)
3609         memcpy (children, node->children, sizeof (GType) * node->n_children);
3610       children[node->n_children] = 0;
3611       
3612       if (n_children)
3613         *n_children = node->n_children;
3614       G_READ_UNLOCK (&type_rw_lock);
3615       
3616       return children;
3617     }
3618   else
3619     {
3620       if (n_children)
3621         *n_children = 0;
3622       
3623       return NULL;
3624     }
3625 }
3626
3627 /**
3628  * g_type_interfaces:
3629  * @type: the type to list interface types for
3630  * @n_interfaces: (out) (optional): location to store the length of
3631  *     the returned array, or %NULL
3632  *
3633  * Return a newly allocated and 0-terminated array of type IDs, listing
3634  * the interface types that @type conforms to.
3635  *
3636  * Returns: (array length=n_interfaces) (transfer full): Newly allocated
3637  *     and 0-terminated array of interface types, free with g_free()
3638  */
3639 GType*
3640 g_type_interfaces (GType  type,
3641                    guint *n_interfaces)
3642 {
3643   TypeNode *node;
3644   
3645   node = lookup_type_node_I (type);
3646   if (node && node->is_instantiatable)
3647     {
3648       IFaceEntries *entries;
3649       GType *ifaces;
3650       guint i;
3651       
3652       G_READ_LOCK (&type_rw_lock);
3653       entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node);
3654       if (entries)
3655         {
3656           ifaces = g_new (GType, IFACE_ENTRIES_N_ENTRIES (entries) + 1);
3657           for (i = 0; i < IFACE_ENTRIES_N_ENTRIES (entries); i++)
3658             ifaces[i] = entries->entry[i].iface_type;
3659         }
3660       else
3661         {
3662           ifaces = g_new (GType, 1);
3663           i = 0;
3664         }
3665       ifaces[i] = 0;
3666       
3667       if (n_interfaces)
3668         *n_interfaces = i;
3669       G_READ_UNLOCK (&type_rw_lock);
3670       
3671       return ifaces;
3672     }
3673   else
3674     {
3675       if (n_interfaces)
3676         *n_interfaces = 0;
3677       
3678       return NULL;
3679     }
3680 }
3681
3682 typedef struct _QData QData;
3683 struct _GData
3684 {
3685   guint  n_qdatas;
3686   QData *qdatas;
3687 };
3688 struct _QData
3689 {
3690   GQuark   quark;
3691   gpointer data;
3692 };
3693
3694 static inline gpointer
3695 type_get_qdata_L (TypeNode *node,
3696                   GQuark    quark)
3697 {
3698   GData *gdata = node->global_gdata;
3699   
3700   if (quark && gdata && gdata->n_qdatas)
3701     {
3702       QData *qdatas = gdata->qdatas - 1;
3703       guint n_qdatas = gdata->n_qdatas;
3704       
3705       do
3706         {
3707           guint i;
3708           QData *check;
3709           
3710           i = (n_qdatas + 1) / 2;
3711           check = qdatas + i;
3712           if (quark == check->quark)
3713             return check->data;
3714           else if (quark > check->quark)
3715             {
3716               n_qdatas -= i;
3717               qdatas = check;
3718             }
3719           else /* if (quark < check->quark) */
3720             n_qdatas = i - 1;
3721         }
3722       while (n_qdatas);
3723     }
3724   return NULL;
3725 }
3726
3727 /**
3728  * g_type_get_qdata:
3729  * @type: a #GType
3730  * @quark: a #GQuark id to identify the data
3731  *
3732  * Obtains data which has previously been attached to @type
3733  * with g_type_set_qdata().
3734  *
3735  * Note that this does not take subtyping into account; data
3736  * attached to one type with g_type_set_qdata() cannot
3737  * be retrieved from a subtype using g_type_get_qdata().
3738  *
3739  * Returns: (transfer none): the data, or %NULL if no data was found
3740  */
3741 gpointer
3742 g_type_get_qdata (GType  type,
3743                   GQuark quark)
3744 {
3745   TypeNode *node;
3746   gpointer data;
3747   
3748   node = lookup_type_node_I (type);
3749   if (node)
3750     {
3751       G_READ_LOCK (&type_rw_lock);
3752       data = type_get_qdata_L (node, quark);
3753       G_READ_UNLOCK (&type_rw_lock);
3754     }
3755   else
3756     {
3757       g_return_val_if_fail (node != NULL, NULL);
3758       data = NULL;
3759     }
3760   return data;
3761 }
3762
3763 static inline void
3764 type_set_qdata_W (TypeNode *node,
3765                   GQuark    quark,
3766                   gpointer  data)
3767 {
3768   GData *gdata;
3769   QData *qdata;
3770   guint i;
3771   
3772   /* setup qdata list if necessary */
3773   if (!node->global_gdata)
3774     node->global_gdata = g_new0 (GData, 1);
3775   gdata = node->global_gdata;
3776   
3777   /* try resetting old data */
3778   qdata = gdata->qdatas;
3779   for (i = 0; i < gdata->n_qdatas; i++)
3780     if (qdata[i].quark == quark)
3781       {
3782         qdata[i].data = data;
3783         return;
3784       }
3785   
3786   /* add new entry */
3787   gdata->n_qdatas++;
3788   gdata->qdatas = g_renew (QData, gdata->qdatas, gdata->n_qdatas);
3789   qdata = gdata->qdatas;
3790   for (i = 0; i < gdata->n_qdatas - 1; i++)
3791     if (qdata[i].quark > quark)
3792       break;
3793   memmove (qdata + i + 1, qdata + i, sizeof (qdata[0]) * (gdata->n_qdatas - i - 1));
3794   qdata[i].quark = quark;
3795   qdata[i].data = data;
3796 }
3797
3798 /**
3799  * g_type_set_qdata:
3800  * @type: a #GType
3801  * @quark: a #GQuark id to identify the data
3802  * @data: the data
3803  *
3804  * Attaches arbitrary data to a type.
3805  */
3806 void
3807 g_type_set_qdata (GType    type,
3808                   GQuark   quark,
3809                   gpointer data)
3810 {
3811   TypeNode *node;
3812   
3813   g_return_if_fail (quark != 0);
3814   
3815   node = lookup_type_node_I (type);
3816   if (node)
3817     {
3818       G_WRITE_LOCK (&type_rw_lock);
3819       type_set_qdata_W (node, quark, data);
3820       G_WRITE_UNLOCK (&type_rw_lock);
3821     }
3822   else
3823     g_return_if_fail (node != NULL);
3824 }
3825
3826 static void
3827 type_add_flags_W (TypeNode  *node,
3828                   GTypeFlags flags)
3829 {
3830   guint dflags;
3831   
3832   g_return_if_fail ((flags & ~TYPE_FLAG_MASK) == 0);
3833   g_return_if_fail (node != NULL);
3834   
3835   if ((flags & TYPE_FLAG_MASK) && node->is_classed && node->data && node->data->class.class)
3836     g_warning ("tagging type '%s' as abstract after class initialization", NODE_NAME (node));
3837   dflags = GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags));
3838   dflags |= flags;
3839   type_set_qdata_W (node, static_quark_type_flags, GUINT_TO_POINTER (dflags));
3840 }
3841
3842 /**
3843  * g_type_query:
3844  * @type: #GType of a static, classed type
3845  * @query: (out caller-allocates): a user provided structure that is
3846  *     filled in with constant values upon success
3847  *
3848  * Queries the type system for information about a specific type.
3849  * This function will fill in a user-provided structure to hold
3850  * type-specific information. If an invalid #GType is passed in, the
3851  * @type member of the #GTypeQuery is 0. All members filled into the
3852  * #GTypeQuery structure should be considered constant and have to be
3853  * left untouched.
3854  */
3855 void
3856 g_type_query (GType       type,
3857               GTypeQuery *query)
3858 {
3859   TypeNode *node;
3860   
3861   g_return_if_fail (query != NULL);
3862   
3863   /* if node is not static and classed, we won't allow query */
3864   query->type = 0;
3865   node = lookup_type_node_I (type);
3866   if (node && node->is_classed && !node->plugin)
3867     {
3868       /* type is classed and probably even instantiatable */
3869       G_READ_LOCK (&type_rw_lock);
3870       if (node->data)   /* type is static or referenced */
3871         {
3872           query->type = NODE_TYPE (node);
3873           query->type_name = NODE_NAME (node);
3874           query->class_size = node->data->class.class_size;
3875           query->instance_size = node->is_instantiatable ? node->data->instance.instance_size : 0;
3876         }
3877       G_READ_UNLOCK (&type_rw_lock);
3878     }
3879 }
3880
3881 /**
3882  * g_type_get_instance_count:
3883  * @type: a #GType
3884  *
3885  * Returns the number of instances allocated of the particular type;
3886  * this is only available if GLib is built with debugging support and
3887  * the instance_count debug flag is set (by setting the GOBJECT_DEBUG
3888  * variable to include instance-count).
3889  *
3890  * Returns: the number of instances allocated of the given type;
3891  *   if instance counts are not available, returns 0.
3892  *
3893  * Since: 2.44
3894  */
3895 int
3896 g_type_get_instance_count (GType type)
3897 {
3898 #ifdef G_ENABLE_DEBUG
3899   TypeNode *node;
3900
3901   node = lookup_type_node_I (type);
3902   g_return_val_if_fail (node != NULL, 0);
3903
3904   return g_atomic_int_get (&node->instance_count);
3905 #else
3906   return 0;
3907 #endif
3908 }
3909
3910 /* --- implementation details --- */
3911 gboolean
3912 g_type_test_flags (GType type,
3913                    guint flags)
3914 {
3915   TypeNode *node;
3916   gboolean result = FALSE;
3917   
3918   node = lookup_type_node_I (type);
3919   if (node)
3920     {
3921       guint fflags = flags & TYPE_FUNDAMENTAL_FLAG_MASK;
3922       guint tflags = flags & TYPE_FLAG_MASK;
3923       
3924       if (fflags)
3925         {
3926           GTypeFundamentalInfo *finfo = type_node_fundamental_info_I (node);
3927           
3928           fflags = (finfo->type_flags & fflags) == fflags;
3929         }
3930       else
3931         fflags = TRUE;
3932       
3933       if (tflags)
3934         {
3935           G_READ_LOCK (&type_rw_lock);
3936           tflags = (tflags & GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags))) == tflags;
3937           G_READ_UNLOCK (&type_rw_lock);
3938         }
3939       else
3940         tflags = TRUE;
3941       
3942       result = tflags && fflags;
3943     }
3944   
3945   return result;
3946 }
3947
3948 /**
3949  * g_type_get_plugin:
3950  * @type: #GType to retrieve the plugin for
3951  *
3952  * Returns the #GTypePlugin structure for @type.
3953  *
3954  * Returns: (transfer none): the corresponding plugin
3955  *     if @type is a dynamic type, %NULL otherwise
3956  */
3957 GTypePlugin*
3958 g_type_get_plugin (GType type)
3959 {
3960   TypeNode *node;
3961   
3962   node = lookup_type_node_I (type);
3963   
3964   return node ? node->plugin : NULL;
3965 }
3966
3967 /**
3968  * g_type_interface_get_plugin:
3969  * @instance_type: #GType of an instantiatable type
3970  * @interface_type: #GType of an interface type
3971  *
3972  * Returns the #GTypePlugin structure for the dynamic interface
3973  * @interface_type which has been added to @instance_type, or %NULL
3974  * if @interface_type has not been added to @instance_type or does
3975  * not have a #GTypePlugin structure. See g_type_add_interface_dynamic().
3976  *
3977  * Returns: (transfer none): the #GTypePlugin for the dynamic
3978  *     interface @interface_type of @instance_type
3979  */
3980 GTypePlugin*
3981 g_type_interface_get_plugin (GType instance_type,
3982                              GType interface_type)
3983 {
3984   TypeNode *node;
3985   TypeNode *iface;
3986   
3987   g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface_type), NULL);    /* G_TYPE_IS_INTERFACE() is an external call: _U */
3988   
3989   node = lookup_type_node_I (instance_type);  
3990   iface = lookup_type_node_I (interface_type);
3991   if (node && iface)
3992     {
3993       IFaceHolder *iholder;
3994       GTypePlugin *plugin;
3995       
3996       G_READ_LOCK (&type_rw_lock);
3997       
3998       iholder = iface_node_get_holders_L (iface);
3999       while (iholder && iholder->instance_type != instance_type)
4000         iholder = iholder->next;
4001       plugin = iholder ? iholder->plugin : NULL;
4002       
4003       G_READ_UNLOCK (&type_rw_lock);
4004       
4005       return plugin;
4006     }
4007   
4008   g_return_val_if_fail (node == NULL, NULL);
4009   g_return_val_if_fail (iface == NULL, NULL);
4010   
4011   g_warning (G_STRLOC ": attempt to look up plugin for invalid instance/interface type pair.");
4012   
4013   return NULL;
4014 }
4015
4016 /**
4017  * g_type_fundamental_next:
4018  *
4019  * Returns the next free fundamental type id which can be used to
4020  * register a new fundamental type with g_type_register_fundamental().
4021  * The returned type ID represents the highest currently registered
4022  * fundamental type identifier.
4023  *
4024  * Returns: the next available fundamental type ID to be registered,
4025  *     or 0 if the type system ran out of fundamental type IDs
4026  */
4027 GType
4028 g_type_fundamental_next (void)
4029 {
4030   GType type;
4031   
4032   G_READ_LOCK (&type_rw_lock);
4033   type = static_fundamental_next;
4034   G_READ_UNLOCK (&type_rw_lock);
4035   type = G_TYPE_MAKE_FUNDAMENTAL (type);
4036   return type <= G_TYPE_FUNDAMENTAL_MAX ? type : 0;
4037 }
4038
4039 /**
4040  * g_type_fundamental:
4041  * @type_id: valid type ID
4042  * 
4043  * Internal function, used to extract the fundamental type ID portion.
4044  * Use G_TYPE_FUNDAMENTAL() instead.
4045  * 
4046  * Returns: fundamental type ID
4047  */
4048 GType
4049 g_type_fundamental (GType type_id)
4050 {
4051   TypeNode *node = lookup_type_node_I (type_id);
4052   
4053   return node ? NODE_FUNDAMENTAL_TYPE (node) : 0;
4054 }
4055
4056 gboolean
4057 g_type_check_instance_is_a (GTypeInstance *type_instance,
4058                             GType          iface_type)
4059 {
4060   TypeNode *node, *iface;
4061   gboolean check;
4062   
4063   if (!type_instance || !type_instance->g_class)
4064     return FALSE;
4065   
4066   node = lookup_type_node_I (type_instance->g_class->g_type);
4067   iface = lookup_type_node_I (iface_type);
4068   check = node && node->is_instantiatable && iface && type_node_conforms_to_U (node, iface, TRUE, FALSE);
4069   
4070   return check;
4071 }
4072
4073 gboolean
4074 g_type_check_instance_is_fundamentally_a (GTypeInstance *type_instance,
4075                                           GType          fundamental_type)
4076 {
4077   TypeNode *node;
4078   if (!type_instance || !type_instance->g_class)
4079     return FALSE;
4080   node = lookup_type_node_I (type_instance->g_class->g_type);
4081   return node && (NODE_FUNDAMENTAL_TYPE(node) == fundamental_type);
4082 }
4083
4084 gboolean
4085 g_type_check_class_is_a (GTypeClass *type_class,
4086                          GType       is_a_type)
4087 {
4088   TypeNode *node, *iface;
4089   gboolean check;
4090   
4091   if (!type_class)
4092     return FALSE;
4093   
4094   node = lookup_type_node_I (type_class->g_type);
4095   iface = lookup_type_node_I (is_a_type);
4096   check = node && node->is_classed && iface && type_node_conforms_to_U (node, iface, FALSE, FALSE);
4097   
4098   return check;
4099 }
4100
4101 GTypeInstance*
4102 g_type_check_instance_cast (GTypeInstance *type_instance,
4103                             GType          iface_type)
4104 {
4105   if (type_instance)
4106     {
4107       if (type_instance->g_class)
4108         {
4109           TypeNode *node, *iface;
4110           gboolean is_instantiatable, check;
4111           
4112           node = lookup_type_node_I (type_instance->g_class->g_type);
4113           is_instantiatable = node && node->is_instantiatable;
4114           iface = lookup_type_node_I (iface_type);
4115           check = is_instantiatable && iface && type_node_conforms_to_U (node, iface, TRUE, FALSE);
4116           if (check)
4117             return type_instance;
4118           
4119           if (is_instantiatable)
4120             g_warning ("invalid cast from '%s' to '%s'",
4121                        type_descriptive_name_I (type_instance->g_class->g_type),
4122                        type_descriptive_name_I (iface_type));
4123           else
4124             g_warning ("invalid uninstantiatable type '%s' in cast to '%s'",
4125                        type_descriptive_name_I (type_instance->g_class->g_type),
4126                        type_descriptive_name_I (iface_type));
4127         }
4128       else
4129         g_warning ("invalid unclassed pointer in cast to '%s'",
4130                    type_descriptive_name_I (iface_type));
4131     }
4132   
4133   return type_instance;
4134 }
4135
4136 GTypeClass*
4137 g_type_check_class_cast (GTypeClass *type_class,
4138                          GType       is_a_type)
4139 {
4140   if (type_class)
4141     {
4142       TypeNode *node, *iface;
4143       gboolean is_classed, check;
4144       
4145       node = lookup_type_node_I (type_class->g_type);
4146       is_classed = node && node->is_classed;
4147       iface = lookup_type_node_I (is_a_type);
4148       check = is_classed && iface && type_node_conforms_to_U (node, iface, FALSE, FALSE);
4149       if (check)
4150         return type_class;
4151       
4152       if (is_classed)
4153         g_warning ("invalid class cast from '%s' to '%s'",
4154                    type_descriptive_name_I (type_class->g_type),
4155                    type_descriptive_name_I (is_a_type));
4156       else
4157         g_warning ("invalid unclassed type '%s' in class cast to '%s'",
4158                    type_descriptive_name_I (type_class->g_type),
4159                    type_descriptive_name_I (is_a_type));
4160     }
4161   else
4162     g_warning ("invalid class cast from (NULL) pointer to '%s'",
4163                type_descriptive_name_I (is_a_type));
4164   return type_class;
4165 }
4166
4167 /**
4168  * g_type_check_instance:
4169  * @instance: a valid #GTypeInstance structure
4170  *
4171  * Private helper function to aid implementation of the
4172  * G_TYPE_CHECK_INSTANCE() macro.
4173  *
4174  * Returns: %TRUE if @instance is valid, %FALSE otherwise
4175  */
4176 gboolean
4177 g_type_check_instance (GTypeInstance *type_instance)
4178 {
4179   /* this function is just here to make the signal system
4180    * conveniently elaborated on instance checks
4181    */
4182   if (type_instance)
4183     {
4184       if (type_instance->g_class)
4185         {
4186           TypeNode *node = lookup_type_node_I (type_instance->g_class->g_type);
4187           
4188           if (node && node->is_instantiatable)
4189             return TRUE;
4190           
4191           g_warning ("instance of invalid non-instantiatable type '%s'",
4192                      type_descriptive_name_I (type_instance->g_class->g_type));
4193         }
4194       else
4195         g_warning ("instance with invalid (NULL) class pointer");
4196     }
4197   else
4198     g_warning ("invalid (NULL) pointer instance");
4199   
4200   return FALSE;
4201 }
4202
4203 static inline gboolean
4204 type_check_is_value_type_U (GType type)
4205 {
4206   GTypeFlags tflags = G_TYPE_FLAG_VALUE_ABSTRACT;
4207   TypeNode *node;
4208   
4209   /* common path speed up */
4210   node = lookup_type_node_I (type);
4211   if (node && node->mutatable_check_cache)
4212     return TRUE;
4213   
4214   G_READ_LOCK (&type_rw_lock);
4215  restart_check:
4216   if (node)
4217     {
4218       if (node->data && NODE_REFCOUNT (node) > 0 &&
4219           node->data->common.value_table->value_init)
4220         tflags = GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags));
4221       else if (NODE_IS_IFACE (node))
4222         {
4223           guint i;
4224           
4225           for (i = 0; i < IFACE_NODE_N_PREREQUISITES (node); i++)
4226             {
4227               GType prtype = IFACE_NODE_PREREQUISITES (node)[i];
4228               TypeNode *prnode = lookup_type_node_I (prtype);
4229               
4230               if (prnode->is_instantiatable)
4231                 {
4232                   type = prtype;
4233                   node = lookup_type_node_I (type);
4234                   goto restart_check;
4235                 }
4236             }
4237         }
4238     }
4239   G_READ_UNLOCK (&type_rw_lock);
4240   
4241   return !(tflags & G_TYPE_FLAG_VALUE_ABSTRACT);
4242 }
4243
4244 gboolean
4245 g_type_check_is_value_type (GType type)
4246 {
4247   return type_check_is_value_type_U (type);
4248 }
4249
4250 gboolean
4251 g_type_check_value (const GValue *value)
4252 {
4253   return value && type_check_is_value_type_U (value->g_type);
4254 }
4255
4256 gboolean
4257 g_type_check_value_holds (const GValue *value,
4258                           GType         type)
4259 {
4260   return value && type_check_is_value_type_U (value->g_type) && g_type_is_a (value->g_type, type);
4261 }
4262
4263 /**
4264  * g_type_value_table_peek: (skip)
4265  * @type: a #GType
4266  *
4267  * Returns the location of the #GTypeValueTable associated with @type.
4268  *
4269  * Note that this function should only be used from source code
4270  * that implements or has internal knowledge of the implementation of
4271  * @type.
4272  *
4273  * Returns: location of the #GTypeValueTable associated with @type or
4274  *     %NULL if there is no #GTypeValueTable associated with @type
4275  */
4276 GTypeValueTable*
4277 g_type_value_table_peek (GType type)
4278 {
4279   GTypeValueTable *vtable = NULL;
4280   TypeNode *node = lookup_type_node_I (type);
4281   gboolean has_refed_data, has_table;
4282
4283   if (node && NODE_REFCOUNT (node) && node->mutatable_check_cache)
4284     return node->data->common.value_table;
4285
4286   G_READ_LOCK (&type_rw_lock);
4287   
4288  restart_table_peek:
4289   has_refed_data = node && node->data && NODE_REFCOUNT (node) > 0;
4290   has_table = has_refed_data && node->data->common.value_table->value_init;
4291   if (has_refed_data)
4292     {
4293       if (has_table)
4294         vtable = node->data->common.value_table;
4295       else if (NODE_IS_IFACE (node))
4296         {
4297           guint i;
4298           
4299           for (i = 0; i < IFACE_NODE_N_PREREQUISITES (node); i++)
4300             {
4301               GType prtype = IFACE_NODE_PREREQUISITES (node)[i];
4302               TypeNode *prnode = lookup_type_node_I (prtype);
4303               
4304               if (prnode->is_instantiatable)
4305                 {
4306                   type = prtype;
4307                   node = lookup_type_node_I (type);
4308                   goto restart_table_peek;
4309                 }
4310             }
4311         }
4312     }
4313   
4314   G_READ_UNLOCK (&type_rw_lock);
4315   
4316   if (vtable)
4317     return vtable;
4318   
4319   if (!node)
4320     g_warning (G_STRLOC ": type id '%" G_GSIZE_FORMAT "' is invalid", type);
4321   if (!has_refed_data)
4322     g_warning ("can't peek value table for type '%s' which is not currently referenced",
4323                type_descriptive_name_I (type));
4324   
4325   return NULL;
4326 }
4327
4328 const gchar *
4329 g_type_name_from_instance (GTypeInstance *instance)
4330 {
4331   if (!instance)
4332     return "<NULL-instance>";
4333   else
4334     return g_type_name_from_class (instance->g_class);
4335 }
4336
4337 const gchar *
4338 g_type_name_from_class (GTypeClass *g_class)
4339 {
4340   if (!g_class)
4341     return "<NULL-class>";
4342   else
4343     return g_type_name (g_class->g_type);
4344 }
4345
4346
4347 /* --- private api for gboxed.c --- */
4348 gpointer
4349 _g_type_boxed_copy (GType type, gpointer value)
4350 {
4351   TypeNode *node = lookup_type_node_I (type);
4352
4353   return node->data->boxed.copy_func (value);
4354 }
4355
4356 void
4357 _g_type_boxed_free (GType type, gpointer value)
4358 {
4359   TypeNode *node = lookup_type_node_I (type);
4360
4361   node->data->boxed.free_func (value);
4362 }
4363
4364 void
4365 _g_type_boxed_init (GType          type,
4366                     GBoxedCopyFunc copy_func,
4367                     GBoxedFreeFunc free_func)
4368 {
4369   TypeNode *node = lookup_type_node_I (type);
4370
4371   node->data->boxed.copy_func = copy_func;
4372   node->data->boxed.free_func = free_func;
4373 }
4374
4375 /* --- initialization --- */
4376 /**
4377  * g_type_init_with_debug_flags:
4378  * @debug_flags: bitwise combination of #GTypeDebugFlags values for
4379  *     debugging purposes
4380  *
4381  * This function used to initialise the type system with debugging
4382  * flags.  Since GLib 2.36, the type system is initialised automatically
4383  * and this function does nothing.
4384  *
4385  * If you need to enable debugging features, use the GOBJECT_DEBUG
4386  * environment variable.
4387  *
4388  * Deprecated: 2.36: the type system is now initialised automatically
4389  */
4390 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
4391 void
4392 g_type_init_with_debug_flags (GTypeDebugFlags debug_flags)
4393 {
4394   g_assert_type_system_initialized ();
4395
4396   if (debug_flags)
4397     g_message ("g_type_init_with_debug_flags() is no longer supported.  Use the GOBJECT_DEBUG environment variable.");
4398 }
4399 G_GNUC_END_IGNORE_DEPRECATIONS
4400
4401 /**
4402  * g_type_init:
4403  *
4404  * This function used to initialise the type system.  Since GLib 2.36,
4405  * the type system is initialised automatically and this function does
4406  * nothing.
4407  *
4408  * Deprecated: 2.36: the type system is now initialised automatically
4409  */
4410 void
4411 g_type_init (void)
4412 {
4413   g_assert_type_system_initialized ();
4414 }
4415
4416 static void
4417 gobject_init (void)
4418 {
4419   const gchar *env_string;
4420   GTypeInfo info;
4421   TypeNode *node;
4422   GType type G_GNUC_UNUSED  /* when compiling with G_DISABLE_ASSERT */;
4423
4424   /* Ensure GLib is initialized first, see
4425    * https://bugzilla.gnome.org/show_bug.cgi?id=756139
4426    */
4427   GLIB_PRIVATE_CALL (glib_init) ();
4428
4429   G_WRITE_LOCK (&type_rw_lock);
4430
4431   /* setup GObject library wide debugging flags */
4432   env_string = g_getenv ("GOBJECT_DEBUG");
4433   if (env_string != NULL)
4434     {
4435       GDebugKey debug_keys[] = {
4436         { "objects", G_TYPE_DEBUG_OBJECTS },
4437         { "instance-count", G_TYPE_DEBUG_INSTANCE_COUNT },
4438         { "signals", G_TYPE_DEBUG_SIGNALS },
4439       };
4440
4441       _g_type_debug_flags = g_parse_debug_string (env_string, debug_keys, G_N_ELEMENTS (debug_keys));
4442     }
4443
4444   /* quarks */
4445   static_quark_type_flags = g_quark_from_static_string ("-g-type-private--GTypeFlags");
4446   static_quark_iface_holder = g_quark_from_static_string ("-g-type-private--IFaceHolder");
4447   static_quark_dependants_array = g_quark_from_static_string ("-g-type-private--dependants-array");
4448
4449   /* type qname hash table */
4450   static_type_nodes_ht = g_hash_table_new (g_str_hash, g_str_equal);
4451
4452   /* invalid type G_TYPE_INVALID (0)
4453    */
4454   static_fundamental_type_nodes[0] = NULL;
4455
4456   /* void type G_TYPE_NONE
4457    */
4458   node = type_node_fundamental_new_W (G_TYPE_NONE, g_intern_static_string ("void"), 0);
4459   type = NODE_TYPE (node);
4460   g_assert (type == G_TYPE_NONE);
4461
4462   /* interface fundamental type G_TYPE_INTERFACE (!classed)
4463    */
4464   memset (&info, 0, sizeof (info));
4465   node = type_node_fundamental_new_W (G_TYPE_INTERFACE, g_intern_static_string ("GInterface"), G_TYPE_FLAG_DERIVABLE);
4466   type = NODE_TYPE (node);
4467   type_data_make_W (node, &info, NULL);
4468   g_assert (type == G_TYPE_INTERFACE);
4469
4470   G_WRITE_UNLOCK (&type_rw_lock);
4471
4472   _g_value_c_init ();
4473
4474   /* G_TYPE_TYPE_PLUGIN
4475    */
4476   g_type_ensure (g_type_plugin_get_type ());
4477
4478   /* G_TYPE_* value types
4479    */
4480   _g_value_types_init ();
4481
4482   /* G_TYPE_ENUM & G_TYPE_FLAGS
4483    */
4484   _g_enum_types_init ();
4485
4486   /* G_TYPE_BOXED
4487    */
4488   _g_boxed_type_init ();
4489
4490   /* G_TYPE_PARAM
4491    */
4492   _g_param_type_init ();
4493
4494   /* G_TYPE_OBJECT
4495    */
4496   _g_object_type_init ();
4497
4498   /* G_TYPE_PARAM_* pspec types
4499    */
4500   _g_param_spec_types_init ();
4501
4502   /* Value Transformations
4503    */
4504   _g_value_transforms_init ();
4505
4506   /* Signal system
4507    */
4508   _g_signal_init ();
4509 }
4510
4511 #if defined (G_OS_WIN32)
4512
4513 BOOL WINAPI DllMain (HINSTANCE hinstDLL,
4514                      DWORD     fdwReason,
4515                      LPVOID    lpvReserved);
4516
4517 BOOL WINAPI
4518 DllMain (HINSTANCE hinstDLL,
4519          DWORD     fdwReason,
4520          LPVOID    lpvReserved)
4521 {
4522   switch (fdwReason)
4523     {
4524     case DLL_PROCESS_ATTACH:
4525       gobject_init ();
4526       break;
4527
4528     default:
4529       /* do nothing */
4530       ;
4531     }
4532
4533   return TRUE;
4534 }
4535
4536 #elif defined (G_HAS_CONSTRUCTORS)
4537 #ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
4538 #pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(gobject_init_ctor)
4539 #endif
4540 G_DEFINE_CONSTRUCTOR(gobject_init_ctor)
4541
4542 static void
4543 gobject_init_ctor (void)
4544 {
4545   gobject_init ();
4546 }
4547
4548 #else
4549 # error Your platform/compiler is missing constructor support
4550 #endif
4551
4552 /**
4553  * g_type_class_add_private:
4554  * @g_class: (type GObject.TypeClass): class structure for an instantiatable
4555  *    type
4556  * @private_size: size of private structure
4557  *
4558  * Registers a private structure for an instantiatable type.
4559  *
4560  * When an object is allocated, the private structures for
4561  * the type and all of its parent types are allocated
4562  * sequentially in the same memory block as the public
4563  * structures, and are zero-filled.
4564  *
4565  * Note that the accumulated size of the private structures of
4566  * a type and all its parent types cannot exceed 64 KiB.
4567  *
4568  * This function should be called in the type's class_init() function.
4569  * The private structure can be retrieved using the
4570  * G_TYPE_INSTANCE_GET_PRIVATE() macro.
4571  *
4572  * The following example shows attaching a private structure
4573  * MyObjectPrivate to an object MyObject defined in the standard
4574  * GObject fashion in the type's class_init() function.
4575  *
4576  * Note the use of a structure member "priv" to avoid the overhead
4577  * of repeatedly calling MY_OBJECT_GET_PRIVATE().
4578  *
4579  * |[<!-- language="C" --> 
4580  * typedef struct _MyObject        MyObject;
4581  * typedef struct _MyObjectPrivate MyObjectPrivate;
4582  *
4583  * struct _MyObject {
4584  *  GObject parent;
4585  *
4586  *  MyObjectPrivate *priv;
4587  * };
4588  *
4589  * struct _MyObjectPrivate {
4590  *   int some_field;
4591  * };
4592  *
4593  * static void
4594  * my_object_class_init (MyObjectClass *klass)
4595  * {
4596  *   g_type_class_add_private (klass, sizeof (MyObjectPrivate));
4597  * }
4598  *
4599  * static void
4600  * my_object_init (MyObject *my_object)
4601  * {
4602  *   my_object->priv = G_TYPE_INSTANCE_GET_PRIVATE (my_object,
4603  *                                                  MY_TYPE_OBJECT,
4604  *                                                  MyObjectPrivate);
4605  *   // my_object->priv->some_field will be automatically initialised to 0
4606  * }
4607  *
4608  * static int
4609  * my_object_get_some_field (MyObject *my_object)
4610  * {
4611  *   MyObjectPrivate *priv;
4612  *
4613  *   g_return_val_if_fail (MY_IS_OBJECT (my_object), 0);
4614  *
4615  *   priv = my_object->priv;
4616  *
4617  *   return priv->some_field;
4618  * }
4619  * ]|
4620  *
4621  * Since: 2.4
4622  * Deprecated: 2.58: Use the G_ADD_PRIVATE() macro with the `G_DEFINE_*`
4623  *   family of macros to add instance private data to a type
4624  */
4625 void
4626 g_type_class_add_private (gpointer g_class,
4627                           gsize    private_size)
4628 {
4629   GType instance_type = ((GTypeClass *)g_class)->g_type;
4630   TypeNode *node = lookup_type_node_I (instance_type);
4631
4632   g_return_if_fail (private_size > 0);
4633   g_return_if_fail (private_size <= 0xffff);
4634
4635   if (!node || !node->is_instantiatable || !node->data || node->data->class.class != g_class)
4636     {
4637       g_warning ("cannot add private field to invalid (non-instantiatable) type '%s'",
4638                  type_descriptive_name_I (instance_type));
4639       return;
4640     }
4641
4642   if (NODE_PARENT_TYPE (node))
4643     {
4644       TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
4645       if (node->data->instance.private_size != pnode->data->instance.private_size)
4646         {
4647           g_warning ("g_type_class_add_private() called multiple times for the same type");
4648           return;
4649         }
4650     }
4651   
4652   G_WRITE_LOCK (&type_rw_lock);
4653
4654   private_size = ALIGN_STRUCT (node->data->instance.private_size + private_size);
4655   g_assert (private_size <= 0xffff);
4656   node->data->instance.private_size = private_size;
4657   
4658   G_WRITE_UNLOCK (&type_rw_lock);
4659 }
4660
4661 /* semi-private, called only by the G_ADD_PRIVATE macro */
4662 gint
4663 g_type_add_instance_private (GType class_gtype,
4664                              gsize private_size)
4665 {
4666   TypeNode *node = lookup_type_node_I (class_gtype);
4667
4668   g_return_val_if_fail (private_size > 0, 0);
4669   g_return_val_if_fail (private_size <= 0xffff, 0);
4670
4671   if (!node || !node->is_classed || !node->is_instantiatable || !node->data)
4672     {
4673       g_warning ("cannot add private field to invalid (non-instantiatable) type '%s'",
4674                  type_descriptive_name_I (class_gtype));
4675       return 0;
4676     }
4677
4678   if (node->plugin != NULL)
4679     {
4680       g_warning ("cannot use g_type_add_instance_private() with dynamic type '%s'",
4681                  type_descriptive_name_I (class_gtype));
4682       return 0;
4683     }
4684
4685   /* in the future, we want to register the private data size of a type
4686    * directly from the get_type() implementation so that we can take full
4687    * advantage of the type definition macros that we already have.
4688    *
4689    * unfortunately, this does not behave correctly if a class in the middle
4690    * of the type hierarchy uses the "old style" of private data registration
4691    * from the class_init() implementation, as the private data offset is not
4692    * going to be known until the full class hierarchy is initialized.
4693    *
4694    * in order to transition our code to the Glorious New Future™, we proceed
4695    * with a two-step implementation: first, we provide this new function to
4696    * register the private data size in the get_type() implementation and we
4697    * hide it behind a macro. the function will return the private size, instead
4698    * of the offset, which will be stored inside a static variable defined by
4699    * the G_DEFINE_TYPE_EXTENDED macro. the G_DEFINE_TYPE_EXTENDED macro will
4700    * check the variable and call g_type_class_add_instance_private(), which
4701    * will use the data size and actually register the private data, then
4702    * return the computed offset of the private data, which will be stored
4703    * inside the static variable, so we can use it to retrieve the pointer
4704    * to the private data structure.
4705    *
4706    * once all our code has been migrated to the new idiomatic form of private
4707    * data registration, we will change the g_type_add_instance_private()
4708    * function to actually perform the registration and return the offset
4709    * of the private data; g_type_class_add_instance_private() already checks
4710    * if the passed argument is negative (meaning that it's an offset in the
4711    * GTypeInstance allocation) and becomes a no-op if that's the case. this
4712    * should make the migration fully transparent even if we're effectively
4713    * copying this macro into everybody's code.
4714    */
4715   return private_size;
4716 }
4717
4718 /* semi-private function, should only be used by G_DEFINE_TYPE_EXTENDED */
4719 void
4720 g_type_class_adjust_private_offset (gpointer  g_class,
4721                                     gint     *private_size_or_offset)
4722 {
4723   GType class_gtype = ((GTypeClass *) g_class)->g_type;
4724   TypeNode *node = lookup_type_node_I (class_gtype);
4725   gssize private_size;
4726
4727   g_return_if_fail (private_size_or_offset != NULL);
4728
4729   /* if we have been passed the offset instead of the private data size,
4730    * then we consider this as a no-op, and just return the value. see the
4731    * comment in g_type_add_instance_private() for the full explanation.
4732    */
4733   if (*private_size_or_offset > 0)
4734     g_return_if_fail (*private_size_or_offset <= 0xffff);
4735   else
4736     return;
4737
4738   if (!node || !node->is_classed || !node->is_instantiatable || !node->data)
4739     {
4740       g_warning ("cannot add private field to invalid (non-instantiatable) type '%s'",
4741                  type_descriptive_name_I (class_gtype));
4742       *private_size_or_offset = 0;
4743       return;
4744     }
4745
4746   if (NODE_PARENT_TYPE (node))
4747     {
4748       TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
4749       if (node->data->instance.private_size != pnode->data->instance.private_size)
4750         {
4751           g_warning ("g_type_add_instance_private() called multiple times for the same type");
4752           *private_size_or_offset = 0;
4753           return;
4754         }
4755     }
4756
4757   G_WRITE_LOCK (&type_rw_lock);
4758
4759   private_size = ALIGN_STRUCT (node->data->instance.private_size + *private_size_or_offset);
4760   g_assert (private_size <= 0xffff);
4761   node->data->instance.private_size = private_size;
4762
4763   *private_size_or_offset = -(gint) node->data->instance.private_size;
4764
4765   G_WRITE_UNLOCK (&type_rw_lock);
4766 }
4767
4768 gpointer
4769 g_type_instance_get_private (GTypeInstance *instance,
4770                              GType          private_type)
4771 {
4772   TypeNode *node;
4773
4774   g_return_val_if_fail (instance != NULL && instance->g_class != NULL, NULL);
4775
4776   node = lookup_type_node_I (private_type);
4777   if (G_UNLIKELY (!node || !node->is_instantiatable))
4778     {
4779       g_warning ("instance of invalid non-instantiatable type '%s'",
4780                  type_descriptive_name_I (instance->g_class->g_type));
4781       return NULL;
4782     }
4783
4784   return ((gchar *) instance) - node->data->instance.private_size;
4785 }
4786
4787 /**
4788  * g_type_class_get_instance_private_offset: (skip)
4789  * @g_class: (type GObject.TypeClass): a #GTypeClass
4790  *
4791  * Gets the offset of the private data for instances of @g_class.
4792  *
4793  * This is how many bytes you should add to the instance pointer of a
4794  * class in order to get the private data for the type represented by
4795  * @g_class.
4796  *
4797  * You can only call this function after you have registered a private
4798  * data area for @g_class using g_type_class_add_private().
4799  *
4800  * Returns: the offset, in bytes
4801  *
4802  * Since: 2.38
4803  **/
4804 gint
4805 g_type_class_get_instance_private_offset (gpointer g_class)
4806 {
4807   GType instance_type;
4808   guint16 parent_size;
4809   TypeNode *node;
4810
4811   g_assert (g_class != NULL);
4812
4813   instance_type = ((GTypeClass *) g_class)->g_type;
4814   node = lookup_type_node_I (instance_type);
4815
4816   g_assert (node != NULL);
4817   g_assert (node->is_instantiatable);
4818
4819   if (NODE_PARENT_TYPE (node))
4820     {
4821       TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
4822
4823       parent_size = pnode->data->instance.private_size;
4824     }
4825   else
4826     parent_size = 0;
4827
4828   if (node->data->instance.private_size == parent_size)
4829     g_error ("g_type_class_get_instance_private_offset() called on class %s but it has no private data",
4830              g_type_name (instance_type));
4831
4832   return -(gint) node->data->instance.private_size;
4833 }
4834
4835 /**
4836  * g_type_add_class_private:
4837  * @class_type: GType of a classed type
4838  * @private_size: size of private structure
4839  *
4840  * Registers a private class structure for a classed type;
4841  * when the class is allocated, the private structures for
4842  * the class and all of its parent types are allocated
4843  * sequentially in the same memory block as the public
4844  * structures, and are zero-filled.
4845  *
4846  * This function should be called in the
4847  * type's get_type() function after the type is registered.
4848  * The private structure can be retrieved using the
4849  * G_TYPE_CLASS_GET_PRIVATE() macro.
4850  *
4851  * Since: 2.24
4852  */
4853 void
4854 g_type_add_class_private (GType    class_type,
4855                           gsize    private_size)
4856 {
4857   TypeNode *node = lookup_type_node_I (class_type);
4858   gsize offset;
4859
4860   g_return_if_fail (private_size > 0);
4861
4862   if (!node || !node->is_classed || !node->data)
4863     {
4864       g_warning ("cannot add class private field to invalid type '%s'",
4865                  type_descriptive_name_I (class_type));
4866       return;
4867     }
4868
4869   if (NODE_PARENT_TYPE (node))
4870     {
4871       TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
4872       if (node->data->class.class_private_size != pnode->data->class.class_private_size)
4873         {
4874           g_warning ("g_type_add_class_private() called multiple times for the same type");
4875           return;
4876         }
4877     }
4878   
4879   G_WRITE_LOCK (&type_rw_lock);
4880
4881   offset = ALIGN_STRUCT (node->data->class.class_private_size);
4882   node->data->class.class_private_size = offset + private_size;
4883
4884   G_WRITE_UNLOCK (&type_rw_lock);
4885 }
4886
4887 gpointer
4888 g_type_class_get_private (GTypeClass *klass,
4889                           GType       private_type)
4890 {
4891   TypeNode *class_node;
4892   TypeNode *private_node;
4893   TypeNode *parent_node;
4894   gsize offset;
4895
4896   g_return_val_if_fail (klass != NULL, NULL);
4897
4898   class_node = lookup_type_node_I (klass->g_type);
4899   if (G_UNLIKELY (!class_node || !class_node->is_classed))
4900     {
4901       g_warning ("class of invalid type '%s'",
4902                  type_descriptive_name_I (klass->g_type));
4903       return NULL;
4904     }
4905
4906   private_node = lookup_type_node_I (private_type);
4907   if (G_UNLIKELY (!private_node || !NODE_IS_ANCESTOR (private_node, class_node)))
4908     {
4909       g_warning ("attempt to retrieve private data for invalid type '%s'",
4910                  type_descriptive_name_I (private_type));
4911       return NULL;
4912     }
4913
4914   offset = ALIGN_STRUCT (class_node->data->class.class_size);
4915
4916   if (NODE_PARENT_TYPE (private_node))
4917     {
4918       parent_node = lookup_type_node_I (NODE_PARENT_TYPE (private_node));
4919       g_assert (parent_node->data && NODE_REFCOUNT (parent_node) > 0);
4920
4921       if (G_UNLIKELY (private_node->data->class.class_private_size == parent_node->data->class.class_private_size))
4922         {
4923           g_warning ("g_type_instance_get_class_private() requires a prior call to g_type_add_class_private()");
4924           return NULL;
4925         }
4926
4927       offset += ALIGN_STRUCT (parent_node->data->class.class_private_size);
4928     }
4929
4930   return G_STRUCT_MEMBER_P (klass, offset);
4931 }
4932
4933 /**
4934  * g_type_ensure:
4935  * @type: a #GType
4936  *
4937  * Ensures that the indicated @type has been registered with the
4938  * type system, and its _class_init() method has been run.
4939  *
4940  * In theory, simply calling the type's _get_type() method (or using
4941  * the corresponding macro) is supposed take care of this. However,
4942  * _get_type() methods are often marked %G_GNUC_CONST for performance
4943  * reasons, even though this is technically incorrect (since
4944  * %G_GNUC_CONST requires that the function not have side effects,
4945  * which _get_type() methods do on the first call). As a result, if
4946  * you write a bare call to a _get_type() macro, it may get optimized
4947  * out by the compiler. Using g_type_ensure() guarantees that the
4948  * type's _get_type() method is called.
4949  *
4950  * Since: 2.34
4951  */
4952 void
4953 g_type_ensure (GType type)
4954 {
4955   /* In theory, @type has already been resolved and so there's nothing
4956    * to do here. But this protects us in the case where the function
4957    * gets inlined (as it might in gobject_init_ctor() above).
4958    */
4959   if (G_UNLIKELY (type == (GType)-1))
4960     g_error ("can't happen");
4961 }