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