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