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