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 #ifdef GSTREAMER_LITE 2004 if (entry == NULL) 2005 return FALSE; 2006 #endif // GSTREAMER_LITE 2007 2008 g_assert (iface->data && entry && entry->vtable == NULL && iholder && iholder->info); 2009 2010 entry->init_state = IFACE_INIT; 2011 2012 pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); 2013 if (pnode) /* want to copy over parent iface contents */ 2014 { 2015 IFaceEntry *pentry = type_lookup_iface_entry_L (pnode, iface); 2016 2017 if (pentry) 2018 vtable = g_memdup (pentry->vtable, iface->data->iface.vtable_size); 2019 } 2020 if (!vtable) 2021 vtable = g_memdup (iface->data->iface.dflt_vtable, iface->data->iface.vtable_size); 2022 entry->vtable = vtable; 2023 vtable->g_type = NODE_TYPE (iface); 2024 vtable->g_instance_type = NODE_TYPE (node); 2025 2026 if (iface->data->iface.vtable_init_base) 2027 { 2028 G_WRITE_UNLOCK (&type_rw_lock); 2029 iface->data->iface.vtable_init_base (vtable); 2030 G_WRITE_LOCK (&type_rw_lock); 2031 } 2032 return TRUE; /* initialized the vtable */ 2033 } 2034 2035 /* Finishes what type_iface_vtable_base_init_Wm started by 2036 * calling the interface init function. 2037 * this function may only be called for types with their 2038 * own interface holder info, i.e. types for which 2039 * g_type_add_interface*() was called and not children thereof. 2040 */ 2041 static void 2042 type_iface_vtable_iface_init_Wm (TypeNode *iface, 2043 TypeNode *node) 2044 { 2045 IFaceEntry *entry = type_lookup_iface_entry_L (node, iface); 2046 IFaceHolder *iholder = type_iface_peek_holder_L (iface, NODE_TYPE (node)); 2047 GTypeInterface *vtable = NULL; 2048 guint i; 2049 2050 /* iholder->info should have been filled in by type_iface_vtable_base_init_Wm() */ 2051 g_assert (iface->data && entry && iholder && iholder->info); 2052 g_assert (entry->init_state == IFACE_INIT); /* assert prior base_init() */ 2053 #ifdef GSTREAMER_LITE 2054 if (entry == NULL) 2055 return; 2056 #endif // GSTREAMER_LITE 2057 2058 entry->init_state = INITIALIZED; 2059 2060 vtable = entry->vtable; 2061 2062 if (iholder->info->interface_init) 2063 { 2064 G_WRITE_UNLOCK (&type_rw_lock); 2065 if (iholder->info->interface_init) 2066 iholder->info->interface_init (vtable, iholder->info->interface_data); 2067 G_WRITE_LOCK (&type_rw_lock); 2068 } 2069 2070 for (i = 0; i < static_n_iface_check_funcs; i++) 2071 { 2072 GTypeInterfaceCheckFunc check_func = static_iface_check_funcs[i].check_func; 2073 gpointer check_data = static_iface_check_funcs[i].check_data; 2074 2075 G_WRITE_UNLOCK (&type_rw_lock); 2076 check_func (check_data, (gpointer)vtable); 2077 G_WRITE_LOCK (&type_rw_lock); 2078 } 2079 } 2080 2081 static gboolean 2082 type_iface_vtable_finalize_Wm (TypeNode *iface, 2083 TypeNode *node, 2084 GTypeInterface *vtable) 2085 { 2086 IFaceEntry *entry = type_lookup_iface_entry_L (node, iface); 2087 IFaceHolder *iholder; 2088 2089 /* type_iface_retrieve_holder_info_Wm() doesn't modify write lock for returning NULL */ 2090 iholder = type_iface_retrieve_holder_info_Wm (iface, NODE_TYPE (node), FALSE); 2091 if (!iholder) 2092 return FALSE; /* we don't modify write lock upon FALSE */ 2093 2094 g_assert (entry && entry->vtable == vtable && iholder->info); 2095 2096 entry->vtable = NULL; 2097 entry->init_state = UNINITIALIZED; 2098 if (iholder->info->interface_finalize || iface->data->iface.vtable_finalize_base) 2099 { 2100 G_WRITE_UNLOCK (&type_rw_lock); 2101 if (iholder->info->interface_finalize) 2102 iholder->info->interface_finalize (vtable, iholder->info->interface_data); 2103 if (iface->data->iface.vtable_finalize_base) 2104 iface->data->iface.vtable_finalize_base (vtable); 2105 G_WRITE_LOCK (&type_rw_lock); 2106 } 2107 vtable->g_type = 0; 2108 vtable->g_instance_type = 0; 2109 g_free (vtable); 2110 2111 type_iface_blow_holder_info_Wm (iface, NODE_TYPE (node)); 2112 2113 return TRUE; /* write lock modified */ 2114 } 2115 2116 static void 2117 type_class_init_Wm (TypeNode *node, 2118 GTypeClass *pclass) 2119 { 2120 GSList *slist, *init_slist = NULL; 2121 GTypeClass *class; 2122 IFaceEntries *entries; 2123 IFaceEntry *entry; 2124 TypeNode *bnode, *pnode; 2125 guint i; 2126 2127 /* Accessing data->class will work for instantiable types 2128 * too because ClassData is a subset of InstanceData 2129 */ 2130 g_assert (node->is_classed && node->data && 2131 node->data->class.class_size && 2132 !node->data->class.class && 2133 node->data->class.init_state == UNINITIALIZED); 2134 if (node->data->class.class_private_size) 2135 class = g_malloc0 (ALIGN_STRUCT (node->data->class.class_size) + node->data->class.class_private_size); 2136 else 2137 class = g_malloc0 (node->data->class.class_size); 2138 node->data->class.class = class; 2139 g_atomic_int_set (&node->data->class.init_state, BASE_CLASS_INIT); 2140 2141 if (pclass) 2142 { 2143 TypeNode *pnode = lookup_type_node_I (pclass->g_type); 2144 2145 memcpy (class, pclass, pnode->data->class.class_size); 2146 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); 2147 2148 if (node->is_instantiatable) 2149 { 2150 /* We need to initialize the private_size here rather than in 2151 * type_data_make_W() since the class init for the parent 2152 * class may have changed pnode->data->instance.private_size. 2153 */ 2154 node->data->instance.private_size = pnode->data->instance.private_size; 2155 } 2156 } 2157 class->g_type = NODE_TYPE (node); 2158 2159 G_WRITE_UNLOCK (&type_rw_lock); 2160 2161 /* stack all base class initialization functions, so we 2162 * call them in ascending order. 2163 */ 2164 for (bnode = node; bnode; bnode = lookup_type_node_I (NODE_PARENT_TYPE (bnode))) 2165 if (bnode->data->class.class_init_base) 2166 init_slist = g_slist_prepend (init_slist, (gpointer) bnode->data->class.class_init_base); 2167 for (slist = init_slist; slist; slist = slist->next) 2168 { 2169 GBaseInitFunc class_init_base = (GBaseInitFunc) slist->data; 2170 2171 class_init_base (class); 2172 } 2173 g_slist_free (init_slist); 2174 2175 G_WRITE_LOCK (&type_rw_lock); 2176 2177 g_atomic_int_set (&node->data->class.init_state, BASE_IFACE_INIT); 2178 2179 /* Before we initialize the class, base initialize all interfaces, either 2180 * from parent, or through our holder info 2181 */ 2182 pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); 2183 2184 i = 0; 2185 while ((entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node)) != NULL && 2186 i < IFACE_ENTRIES_N_ENTRIES (entries)) 2187 { 2188 entry = &entries->entry[i]; 2189 while (i < IFACE_ENTRIES_N_ENTRIES (entries) && 2190 entry->init_state == IFACE_INIT) 2191 { 2192 entry++; 2193 i++; 2194 } 2195 2196 if (i == IFACE_ENTRIES_N_ENTRIES (entries)) 2197 break; 2198 2199 if (!type_iface_vtable_base_init_Wm (lookup_type_node_I (entry->iface_type), node)) 2200 { 2201 guint j; 2202 IFaceEntries *pentries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (pnode); 2203 2204 /* need to get this interface from parent, type_iface_vtable_base_init_Wm() 2205 * doesn't modify write lock upon FALSE, so entry is still valid; 2206 */ 2207 g_assert (pnode != NULL); 2208 2209 if (pentries) 2210 for (j = 0; j < IFACE_ENTRIES_N_ENTRIES (pentries); j++) 2211 { 2212 IFaceEntry *pentry = &pentries->entry[j]; 2213 2214 if (pentry->iface_type == entry->iface_type) 2215 { 2216 entry->vtable = pentry->vtable; 2217 entry->init_state = INITIALIZED; 2218 break; 2219 } 2220 } 2221 g_assert (entry->vtable != NULL); 2222 } 2223 2224 /* If the write lock was released, additional interface entries might 2225 * have been inserted into CLASSED_NODE_IFACES_ENTRIES (node); they'll 2226 * be base-initialized when inserted, so we don't have to worry that 2227 * we might miss them. Uninitialized entries can only be moved higher 2228 * when new ones are inserted. 2229 */ 2230 i++; 2231 } 2232 2233 g_atomic_int_set (&node->data->class.init_state, CLASS_INIT); 2234 2235 G_WRITE_UNLOCK (&type_rw_lock); 2236 2237 if (node->data->class.class_init) 2238 node->data->class.class_init (class, (gpointer) node->data->class.class_data); 2239 2240 G_WRITE_LOCK (&type_rw_lock); 2241 2242 g_atomic_int_set (&node->data->class.init_state, IFACE_INIT); 2243 2244 /* finish initializing the interfaces through our holder info. 2245 * inherited interfaces are already init_state == INITIALIZED, because 2246 * they either got setup in the above base_init loop, or during 2247 * class_init from within type_add_interface_Wm() for this or 2248 * an anchestor type. 2249 */ 2250 i = 0; 2251 while ((entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node)) != NULL) 2252 { 2253 entry = &entries->entry[i]; 2254 while (i < IFACE_ENTRIES_N_ENTRIES (entries) && 2255 entry->init_state == INITIALIZED) 2256 { 2257 entry++; 2258 i++; 2259 } 2260 2261 if (i == IFACE_ENTRIES_N_ENTRIES (entries)) 2262 break; 2263 2264 type_iface_vtable_iface_init_Wm (lookup_type_node_I (entry->iface_type), node); 2265 2266 /* As in the loop above, additional initialized entries might be inserted 2267 * if the write lock is released, but that's harmless because the entries 2268 * we need to initialize only move higher in the list. 2269 */ 2270 i++; 2271 } 2272 2273 g_atomic_int_set (&node->data->class.init_state, INITIALIZED); 2274 } 2275 2276 static void 2277 type_data_finalize_class_ifaces_Wm (TypeNode *node) 2278 { 2279 guint i; 2280 IFaceEntries *entries; 2281 2282 g_assert (node->is_instantiatable && node->data && node->data->class.class && NODE_REFCOUNT (node) == 0); 2283 2284 reiterate: 2285 entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node); 2286 for (i = 0; entries != NULL && i < IFACE_ENTRIES_N_ENTRIES (entries); i++) 2287 { 2288 IFaceEntry *entry = &entries->entry[i]; 2289 if (entry->vtable) 2290 { 2291 if (type_iface_vtable_finalize_Wm (lookup_type_node_I (entry->iface_type), node, entry->vtable)) 2292 { 2293 /* refetch entries, IFACES_ENTRIES might be modified */ 2294 goto reiterate; 2295 } 2296 else 2297 { 2298 /* type_iface_vtable_finalize_Wm() doesn't modify write lock upon FALSE, 2299 * iface vtable came from parent 2300 */ 2301 entry->vtable = NULL; 2302 entry->init_state = UNINITIALIZED; 2303 } 2304 } 2305 } 2306 } 2307 2308 static void 2309 type_data_finalize_class_U (TypeNode *node, 2310 ClassData *cdata) 2311 { 2312 GTypeClass *class = cdata->class; 2313 TypeNode *bnode; 2314 2315 g_assert (cdata->class && NODE_REFCOUNT (node) == 0); 2316 2317 if (cdata->class_finalize) 2318 cdata->class_finalize (class, (gpointer) cdata->class_data); 2319 2320 /* call all base class destruction functions in descending order 2321 */ 2322 if (cdata->class_finalize_base) 2323 cdata->class_finalize_base (class); 2324 for (bnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); bnode; bnode = lookup_type_node_I (NODE_PARENT_TYPE (bnode))) 2325 if (bnode->data->class.class_finalize_base) 2326 bnode->data->class.class_finalize_base (class); 2327 2328 g_free (cdata->class); 2329 } 2330 2331 static void 2332 type_data_last_unref_Wm (TypeNode *node, 2333 gboolean uncached) 2334 { 2335 g_return_if_fail (node != NULL && node->plugin != NULL); 2336 2337 if (!node->data || NODE_REFCOUNT (node) == 0) 2338 { 2339 g_warning ("cannot drop last reference to unreferenced type '%s'", 2340 NODE_NAME (node)); 2341 return; 2342 } 2343 2344 /* call class cache hooks */ 2345 if (node->is_classed && node->data && node->data->class.class && static_n_class_cache_funcs && !uncached) 2346 { 2347 guint i; 2348 2349 G_WRITE_UNLOCK (&type_rw_lock); 2350 G_READ_LOCK (&type_rw_lock); 2351 for (i = 0; i < static_n_class_cache_funcs; i++) 2352 { 2353 GTypeClassCacheFunc cache_func = static_class_cache_funcs[i].cache_func; 2354 gpointer cache_data = static_class_cache_funcs[i].cache_data; 2355 gboolean need_break; 2356 2357 G_READ_UNLOCK (&type_rw_lock); 2358 need_break = cache_func (cache_data, node->data->class.class); 2359 G_READ_LOCK (&type_rw_lock); 2360 if (!node->data || NODE_REFCOUNT (node) == 0) 2361 INVALID_RECURSION ("GType class cache function ", cache_func, NODE_NAME (node)); 2362 if (need_break) 2363 break; 2364 } 2365 G_READ_UNLOCK (&type_rw_lock); 2366 G_WRITE_LOCK (&type_rw_lock); 2367 } 2368 2369 /* may have been re-referenced meanwhile */ 2370 if (g_atomic_int_dec_and_test ((int *) &node->ref_count)) 2371 { 2372 GType ptype = NODE_PARENT_TYPE (node); 2373 TypeData *tdata; 2374 2375 if (node->is_instantiatable) 2376 { 2377 /* destroy node->data->instance.mem_chunk */ 2378 } 2379 2380 tdata = node->data; 2381 if (node->is_classed && tdata->class.class) 2382 { 2383 if (CLASSED_NODE_IFACES_ENTRIES_LOCKED (node) != NULL) 2384 type_data_finalize_class_ifaces_Wm (node); 2385 node->mutatable_check_cache = FALSE; 2386 node->data = NULL; 2387 G_WRITE_UNLOCK (&type_rw_lock); 2388 type_data_finalize_class_U (node, &tdata->class); 2389 G_WRITE_LOCK (&type_rw_lock); 2390 } 2391 else if (NODE_IS_IFACE (node) && tdata->iface.dflt_vtable) 2392 { 2393 node->mutatable_check_cache = FALSE; 2394 node->data = NULL; 2395 if (tdata->iface.dflt_finalize || tdata->iface.vtable_finalize_base) 2396 { 2397 G_WRITE_UNLOCK (&type_rw_lock); 2398 if (tdata->iface.dflt_finalize) 2399 tdata->iface.dflt_finalize (tdata->iface.dflt_vtable, (gpointer) tdata->iface.dflt_data); 2400 if (tdata->iface.vtable_finalize_base) 2401 tdata->iface.vtable_finalize_base (tdata->iface.dflt_vtable); 2402 G_WRITE_LOCK (&type_rw_lock); 2403 } 2404 g_free (tdata->iface.dflt_vtable); 2405 } 2406 else 2407 { 2408 node->mutatable_check_cache = FALSE; 2409 node->data = NULL; 2410 } 2411 2412 /* freeing tdata->common.value_table and its contents is taken care of 2413 * by allocating it in one chunk with tdata 2414 */ 2415 g_free (tdata); 2416 2417 G_WRITE_UNLOCK (&type_rw_lock); 2418 g_type_plugin_unuse (node->plugin); 2419 if (ptype) 2420 type_data_unref_U (lookup_type_node_I (ptype), FALSE); 2421 G_WRITE_LOCK (&type_rw_lock); 2422 } 2423 } 2424 2425 static inline void 2426 type_data_unref_U (TypeNode *node, 2427 gboolean uncached) 2428 { 2429 guint current; 2430 2431 do { 2432 current = NODE_REFCOUNT (node); 2433 2434 if (current <= 1) 2435 { 2436 if (!node->plugin) 2437 { 2438 g_warning ("static type '%s' unreferenced too often", 2439 NODE_NAME (node)); 2440 return; 2441 } 2442 else 2443 { 2444 /* This is the last reference of a type from a plugin. We are 2445 * experimentally disabling support for unloading type 2446 * plugins, so don't allow the last ref to drop. 2447 */ 2448 return; 2449 } 2450 2451 g_assert (current > 0); 2452 2453 g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */ 2454 G_WRITE_LOCK (&type_rw_lock); 2455 type_data_last_unref_Wm (node, uncached); 2456 G_WRITE_UNLOCK (&type_rw_lock); 2457 g_rec_mutex_unlock (&class_init_rec_mutex); 2458 return; 2459 } 2460 } while (!g_atomic_int_compare_and_exchange ((int *) &node->ref_count, current, current - 1)); 2461 } 2462 2463 /** 2464 * g_type_add_class_cache_func: (skip) 2465 * @cache_data: data to be passed to @cache_func 2466 * @cache_func: a #GTypeClassCacheFunc 2467 * 2468 * Adds a #GTypeClassCacheFunc to be called before the reference count of a 2469 * class goes from one to zero. This can be used to prevent premature class 2470 * destruction. All installed #GTypeClassCacheFunc functions will be chained 2471 * until one of them returns %TRUE. The functions have to check the class id 2472 * passed in to figure whether they actually want to cache the class of this 2473 * type, since all classes are routed through the same #GTypeClassCacheFunc 2474 * chain. 2475 */ 2476 void 2477 g_type_add_class_cache_func (gpointer cache_data, 2478 GTypeClassCacheFunc cache_func) 2479 { 2480 guint i; 2481 2482 g_return_if_fail (cache_func != NULL); 2483 2484 G_WRITE_LOCK (&type_rw_lock); 2485 i = static_n_class_cache_funcs++; 2486 static_class_cache_funcs = g_renew (ClassCacheFunc, static_class_cache_funcs, static_n_class_cache_funcs); 2487 static_class_cache_funcs[i].cache_data = cache_data; 2488 static_class_cache_funcs[i].cache_func = cache_func; 2489 G_WRITE_UNLOCK (&type_rw_lock); 2490 } 2491 2492 /** 2493 * g_type_remove_class_cache_func: (skip) 2494 * @cache_data: data that was given when adding @cache_func 2495 * @cache_func: a #GTypeClassCacheFunc 2496 * 2497 * Removes a previously installed #GTypeClassCacheFunc. The cache 2498 * maintained by @cache_func has to be empty when calling 2499 * g_type_remove_class_cache_func() to avoid leaks. 2500 */ 2501 void 2502 g_type_remove_class_cache_func (gpointer cache_data, 2503 GTypeClassCacheFunc cache_func) 2504 { 2505 gboolean found_it = FALSE; 2506 guint i; 2507 2508 g_return_if_fail (cache_func != NULL); 2509 2510 G_WRITE_LOCK (&type_rw_lock); 2511 for (i = 0; i < static_n_class_cache_funcs; i++) 2512 if (static_class_cache_funcs[i].cache_data == cache_data && 2513 static_class_cache_funcs[i].cache_func == cache_func) 2514 { 2515 static_n_class_cache_funcs--; 2516 memmove (static_class_cache_funcs + i, 2517 static_class_cache_funcs + i + 1, 2518 sizeof (static_class_cache_funcs[0]) * (static_n_class_cache_funcs - i)); 2519 static_class_cache_funcs = g_renew (ClassCacheFunc, static_class_cache_funcs, static_n_class_cache_funcs); 2520 found_it = TRUE; 2521 break; 2522 } 2523 G_WRITE_UNLOCK (&type_rw_lock); 2524 2525 if (!found_it) 2526 g_warning (G_STRLOC ": cannot remove unregistered class cache func %p with data %p", 2527 cache_func, cache_data); 2528 } 2529 2530 2531 /** 2532 * g_type_add_interface_check: (skip) 2533 * @check_data: data to pass to @check_func 2534 * @check_func: function to be called after each interface 2535 * is initialized 2536 * 2537 * Adds a function to be called after an interface vtable is 2538 * initialized for any class (i.e. after the @interface_init 2539 * member of #GInterfaceInfo has been called). 2540 * 2541 * This function is useful when you want to check an invariant 2542 * that depends on the interfaces of a class. For instance, the 2543 * implementation of #GObject uses this facility to check that an 2544 * object implements all of the properties that are defined on its 2545 * interfaces. 2546 * 2547 * Since: 2.4 2548 */ 2549 void 2550 g_type_add_interface_check (gpointer check_data, 2551 GTypeInterfaceCheckFunc check_func) 2552 { 2553 guint i; 2554 2555 g_return_if_fail (check_func != NULL); 2556 2557 G_WRITE_LOCK (&type_rw_lock); 2558 i = static_n_iface_check_funcs++; 2559 static_iface_check_funcs = g_renew (IFaceCheckFunc, static_iface_check_funcs, static_n_iface_check_funcs); 2560 static_iface_check_funcs[i].check_data = check_data; 2561 static_iface_check_funcs[i].check_func = check_func; 2562 G_WRITE_UNLOCK (&type_rw_lock); 2563 } 2564 2565 /** 2566 * g_type_remove_interface_check: (skip) 2567 * @check_data: callback data passed to g_type_add_interface_check() 2568 * @check_func: callback function passed to g_type_add_interface_check() 2569 * 2570 * Removes an interface check function added with 2571 * g_type_add_interface_check(). 2572 * 2573 * Since: 2.4 2574 */ 2575 void 2576 g_type_remove_interface_check (gpointer check_data, 2577 GTypeInterfaceCheckFunc check_func) 2578 { 2579 gboolean found_it = FALSE; 2580 guint i; 2581 2582 g_return_if_fail (check_func != NULL); 2583 2584 G_WRITE_LOCK (&type_rw_lock); 2585 for (i = 0; i < static_n_iface_check_funcs; i++) 2586 if (static_iface_check_funcs[i].check_data == check_data && 2587 static_iface_check_funcs[i].check_func == check_func) 2588 { 2589 static_n_iface_check_funcs--; 2590 memmove (static_iface_check_funcs + i, 2591 static_iface_check_funcs + i + 1, 2592 sizeof (static_iface_check_funcs[0]) * (static_n_iface_check_funcs - i)); 2593 static_iface_check_funcs = g_renew (IFaceCheckFunc, static_iface_check_funcs, static_n_iface_check_funcs); 2594 found_it = TRUE; 2595 break; 2596 } 2597 G_WRITE_UNLOCK (&type_rw_lock); 2598 2599 if (!found_it) 2600 g_warning (G_STRLOC ": cannot remove unregistered class check func %p with data %p", 2601 check_func, check_data); 2602 } 2603 2604 /* --- type registration --- */ 2605 /** 2606 * g_type_register_fundamental: 2607 * @type_id: a predefined type identifier 2608 * @type_name: 0-terminated string used as the name of the new type 2609 * @info: #GTypeInfo structure for this type 2610 * @finfo: #GTypeFundamentalInfo structure for this type 2611 * @flags: bitwise combination of #GTypeFlags values 2612 * 2613 * Registers @type_id as the predefined identifier and @type_name as the 2614 * name of a fundamental type. If @type_id is already registered, or a 2615 * type named @type_name is already registered, the behaviour is undefined. 2616 * The type system uses the information contained in the #GTypeInfo structure 2617 * pointed to by @info and the #GTypeFundamentalInfo structure pointed to by 2618 * @finfo to manage the type and its instances. The value of @flags determines 2619 * additional characteristics of the fundamental type. 2620 * 2621 * Returns: the predefined type identifier 2622 */ 2623 GType 2624 g_type_register_fundamental (GType type_id, 2625 const gchar *type_name, 2626 const GTypeInfo *info, 2627 const GTypeFundamentalInfo *finfo, 2628 GTypeFlags flags) 2629 { 2630 TypeNode *node; 2631 2632 g_assert_type_system_initialized (); 2633 g_return_val_if_fail (type_id > 0, 0); 2634 g_return_val_if_fail (type_name != NULL, 0); 2635 g_return_val_if_fail (info != NULL, 0); 2636 g_return_val_if_fail (finfo != NULL, 0); 2637 2638 if (!check_type_name_I (type_name)) 2639 return 0; 2640 if ((type_id & TYPE_ID_MASK) || 2641 type_id > G_TYPE_FUNDAMENTAL_MAX) 2642 { 2643 g_warning ("attempt to register fundamental type '%s' with invalid type id (%" G_GSIZE_FORMAT ")", 2644 type_name, 2645 type_id); 2646 return 0; 2647 } 2648 if ((finfo->type_flags & G_TYPE_FLAG_INSTANTIATABLE) && 2649 !(finfo->type_flags & G_TYPE_FLAG_CLASSED)) 2650 { 2651 g_warning ("cannot register instantiatable fundamental type '%s' as non-classed", 2652 type_name); 2653 return 0; 2654 } 2655 if (lookup_type_node_I (type_id)) 2656 { 2657 g_warning ("cannot register existing fundamental type '%s' (as '%s')", 2658 type_descriptive_name_I (type_id), 2659 type_name); 2660 return 0; 2661 } 2662 2663 G_WRITE_LOCK (&type_rw_lock); 2664 node = type_node_fundamental_new_W (type_id, type_name, finfo->type_flags); 2665 type_add_flags_W (node, flags); 2666 2667 if (check_type_info_I (NULL, NODE_FUNDAMENTAL_TYPE (node), type_name, info)) 2668 type_data_make_W (node, info, 2669 check_value_table_I (type_name, info->value_table) ? info->value_table : NULL); 2670 G_WRITE_UNLOCK (&type_rw_lock); 2671 2672 return NODE_TYPE (node); 2673 } 2674 2675 /** 2676 * g_type_register_static_simple: (skip) 2677 * @parent_type: type from which this type will be derived 2678 * @type_name: 0-terminated string used as the name of the new type 2679 * @class_size: size of the class structure (see #GTypeInfo) 2680 * @class_init: location of the class initialization function (see #GTypeInfo) 2681 * @instance_size: size of the instance structure (see #GTypeInfo) 2682 * @instance_init: location of the instance initialization function (see #GTypeInfo) 2683 * @flags: bitwise combination of #GTypeFlags values 2684 * 2685 * Registers @type_name as the name of a new static type derived from 2686 * @parent_type. The value of @flags determines the nature (e.g. 2687 * abstract or not) of the type. It works by filling a #GTypeInfo 2688 * struct and calling g_type_register_static(). 2689 * 2690 * Since: 2.12 2691 * 2692 * Returns: the new type identifier 2693 */ 2694 GType 2695 g_type_register_static_simple (GType parent_type, 2696 const gchar *type_name, 2697 guint class_size, 2698 GClassInitFunc class_init, 2699 guint instance_size, 2700 GInstanceInitFunc instance_init, 2701 GTypeFlags flags) 2702 { 2703 GTypeInfo info; 2704 2705 /* Instances are not allowed to be larger than this. If you have a big 2706 * fixed-length array or something, point to it instead. 2707 */ 2708 g_return_val_if_fail (class_size <= G_MAXUINT16, G_TYPE_INVALID); 2709 g_return_val_if_fail (instance_size <= G_MAXUINT16, G_TYPE_INVALID); 2710 2711 info.class_size = class_size; 2712 info.base_init = NULL; 2713 info.base_finalize = NULL; 2714 info.class_init = class_init; 2715 info.class_finalize = NULL; 2716 info.class_data = NULL; 2717 info.instance_size = instance_size; 2718 info.n_preallocs = 0; 2719 info.instance_init = instance_init; 2720 info.value_table = NULL; 2721 2722 return g_type_register_static (parent_type, type_name, &info, flags); 2723 } 2724 2725 /** 2726 * g_type_register_static: 2727 * @parent_type: type from which this type will be derived 2728 * @type_name: 0-terminated string used as the name of the new type 2729 * @info: #GTypeInfo structure for this type 2730 * @flags: bitwise combination of #GTypeFlags values 2731 * 2732 * Registers @type_name as the name of a new static type derived from 2733 * @parent_type. The type system uses the information contained in the 2734 * #GTypeInfo structure pointed to by @info to manage the type and its 2735 * instances (if not abstract). The value of @flags determines the nature 2736 * (e.g. abstract or not) of the type. 2737 * 2738 * Returns: the new type identifier 2739 */ 2740 GType 2741 g_type_register_static (GType parent_type, 2742 const gchar *type_name, 2743 const GTypeInfo *info, 2744 GTypeFlags flags) 2745 { 2746 TypeNode *pnode, *node; 2747 GType type = 0; 2748 2749 g_assert_type_system_initialized (); 2750 g_return_val_if_fail (parent_type > 0, 0); 2751 g_return_val_if_fail (type_name != NULL, 0); 2752 g_return_val_if_fail (info != NULL, 0); 2753 2754 if (!check_type_name_I (type_name) || 2755 !check_derivation_I (parent_type, type_name)) 2756 return 0; 2757 if (info->class_finalize) 2758 { 2759 g_warning ("class finalizer specified for static type '%s'", 2760 type_name); 2761 return 0; 2762 } 2763 2764 pnode = lookup_type_node_I (parent_type); 2765 G_WRITE_LOCK (&type_rw_lock); 2766 type_data_ref_Wm (pnode); 2767 if (check_type_info_I (pnode, NODE_FUNDAMENTAL_TYPE (pnode), type_name, info)) 2768 { 2769 node = type_node_new_W (pnode, type_name, NULL); 2770 type_add_flags_W (node, flags); 2771 type = NODE_TYPE (node); 2772 type_data_make_W (node, info, 2773 check_value_table_I (type_name, info->value_table) ? info->value_table : NULL); 2774 } 2775 G_WRITE_UNLOCK (&type_rw_lock); 2776 2777 return type; 2778 } 2779 2780 /** 2781 * g_type_register_dynamic: 2782 * @parent_type: type from which this type will be derived 2783 * @type_name: 0-terminated string used as the name of the new type 2784 * @plugin: #GTypePlugin structure to retrieve the #GTypeInfo from 2785 * @flags: bitwise combination of #GTypeFlags values 2786 * 2787 * Registers @type_name as the name of a new dynamic type derived from 2788 * @parent_type. The type system uses the information contained in the 2789 * #GTypePlugin structure pointed to by @plugin to manage the type and its 2790 * instances (if not abstract). The value of @flags determines the nature 2791 * (e.g. abstract or not) of the type. 2792 * 2793 * Returns: the new type identifier or #G_TYPE_INVALID if registration failed 2794 */ 2795 GType 2796 g_type_register_dynamic (GType parent_type, 2797 const gchar *type_name, 2798 GTypePlugin *plugin, 2799 GTypeFlags flags) 2800 { 2801 TypeNode *pnode, *node; 2802 GType type; 2803 2804 g_assert_type_system_initialized (); 2805 g_return_val_if_fail (parent_type > 0, 0); 2806 g_return_val_if_fail (type_name != NULL, 0); 2807 g_return_val_if_fail (plugin != NULL, 0); 2808 2809 if (!check_type_name_I (type_name) || 2810 !check_derivation_I (parent_type, type_name) || 2811 !check_plugin_U (plugin, TRUE, FALSE, type_name)) 2812 return 0; 2813 2814 G_WRITE_LOCK (&type_rw_lock); 2815 pnode = lookup_type_node_I (parent_type); 2816 node = type_node_new_W (pnode, type_name, plugin); 2817 type_add_flags_W (node, flags); 2818 type = NODE_TYPE (node); 2819 G_WRITE_UNLOCK (&type_rw_lock); 2820 2821 return type; 2822 } 2823 2824 /** 2825 * g_type_add_interface_static: 2826 * @instance_type: #GType value of an instantiable type 2827 * @interface_type: #GType value of an interface type 2828 * @info: #GInterfaceInfo structure for this 2829 * (@instance_type, @interface_type) combination 2830 * 2831 * Adds the static @interface_type to @instantiable_type. 2832 * The information contained in the #GInterfaceInfo structure 2833 * pointed to by @info is used to manage the relationship. 2834 */ 2835 void 2836 g_type_add_interface_static (GType instance_type, 2837 GType interface_type, 2838 const GInterfaceInfo *info) 2839 { 2840 /* G_TYPE_IS_INSTANTIATABLE() is an external call: _U */ 2841 g_return_if_fail (G_TYPE_IS_INSTANTIATABLE (instance_type)); 2842 g_return_if_fail (g_type_parent (interface_type) == G_TYPE_INTERFACE); 2843 2844 /* we only need to lock class_init_rec_mutex if instance_type already has its 2845 * class initialized, however this function is rarely enough called to take 2846 * the simple route and always acquire class_init_rec_mutex. 2847 */ 2848 g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */ 2849 G_WRITE_LOCK (&type_rw_lock); 2850 if (check_add_interface_L (instance_type, interface_type)) 2851 { 2852 TypeNode *node = lookup_type_node_I (instance_type); 2853 TypeNode *iface = lookup_type_node_I (interface_type); 2854 if (check_interface_info_I (iface, NODE_TYPE (node), info)) 2855 type_add_interface_Wm (node, iface, info, NULL); 2856 } 2857 G_WRITE_UNLOCK (&type_rw_lock); 2858 g_rec_mutex_unlock (&class_init_rec_mutex); 2859 } 2860 2861 /** 2862 * g_type_add_interface_dynamic: 2863 * @instance_type: #GType value of an instantiable type 2864 * @interface_type: #GType value of an interface type 2865 * @plugin: #GTypePlugin structure to retrieve the #GInterfaceInfo from 2866 * 2867 * Adds the dynamic @interface_type to @instantiable_type. The information 2868 * contained in the #GTypePlugin structure pointed to by @plugin 2869 * is used to manage the relationship. 2870 */ 2871 void 2872 g_type_add_interface_dynamic (GType instance_type, 2873 GType interface_type, 2874 GTypePlugin *plugin) 2875 { 2876 TypeNode *node; 2877 /* G_TYPE_IS_INSTANTIATABLE() is an external call: _U */ 2878 g_return_if_fail (G_TYPE_IS_INSTANTIATABLE (instance_type)); 2879 g_return_if_fail (g_type_parent (interface_type) == G_TYPE_INTERFACE); 2880 2881 node = lookup_type_node_I (instance_type); 2882 if (!check_plugin_U (plugin, FALSE, TRUE, NODE_NAME (node))) 2883 return; 2884 2885 /* see comment in g_type_add_interface_static() about class_init_rec_mutex */ 2886 g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */ 2887 G_WRITE_LOCK (&type_rw_lock); 2888 if (check_add_interface_L (instance_type, interface_type)) 2889 { 2890 TypeNode *iface = lookup_type_node_I (interface_type); 2891 type_add_interface_Wm (node, iface, NULL, plugin); 2892 } 2893 G_WRITE_UNLOCK (&type_rw_lock); 2894 g_rec_mutex_unlock (&class_init_rec_mutex); 2895 } 2896 2897 2898 /* --- public API functions --- */ 2899 /** 2900 * g_type_class_ref: 2901 * @type: type ID of a classed type 2902 * 2903 * Increments the reference count of the class structure belonging to 2904 * @type. This function will demand-create the class if it doesn't 2905 * exist already. 2906 * 2907 * Returns: (type GObject.TypeClass) (transfer none): the #GTypeClass 2908 * structure for the given type ID 2909 */ 2910 gpointer 2911 g_type_class_ref (GType type) 2912 { 2913 TypeNode *node; 2914 GType ptype; 2915 gboolean holds_ref; 2916 GTypeClass *pclass; 2917 2918 /* optimize for common code path */ 2919 node = lookup_type_node_I (type); 2920 if (!node || !node->is_classed) 2921 { 2922 g_warning ("cannot retrieve class for invalid (unclassed) type '%s'", 2923 type_descriptive_name_I (type)); 2924 return NULL; 2925 } 2926 2927 if (G_LIKELY (type_data_ref_U (node))) 2928 { 2929 if (G_LIKELY (g_atomic_int_get (&node->data->class.init_state) == INITIALIZED)) 2930 return node->data->class.class; 2931 holds_ref = TRUE; 2932 } 2933 else 2934 holds_ref = FALSE; 2935 2936 /* here, we either have node->data->class.class == NULL, or a recursive 2937 * call to g_type_class_ref() with a partly initialized class, or 2938 * node->data->class.init_state == INITIALIZED, because any 2939 * concurrently running initialization was guarded by class_init_rec_mutex. 2940 */ 2941 g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */ 2942 2943 /* we need an initialized parent class for initializing derived classes */ 2944 ptype = NODE_PARENT_TYPE (node); 2945 pclass = ptype ? g_type_class_ref (ptype) : NULL; 2946 2947 G_WRITE_LOCK (&type_rw_lock); 2948 2949 if (!holds_ref) 2950 type_data_ref_Wm (node); 2951 2952 if (!node->data->class.class) /* class uninitialized */ 2953 type_class_init_Wm (node, pclass); 2954 2955 G_WRITE_UNLOCK (&type_rw_lock); 2956 2957 if (pclass) 2958 g_type_class_unref (pclass); 2959 2960 g_rec_mutex_unlock (&class_init_rec_mutex); 2961 2962 return node->data->class.class; 2963 } 2964 2965 /** 2966 * g_type_class_unref: 2967 * @g_class: (type GObject.TypeClass): a #GTypeClass structure to unref 2968 * 2969 * Decrements the reference count of the class structure being passed in. 2970 * Once the last reference count of a class has been released, classes 2971 * may be finalized by the type system, so further dereferencing of a 2972 * class pointer after g_type_class_unref() are invalid. 2973 */ 2974 void 2975 g_type_class_unref (gpointer g_class) 2976 { 2977 TypeNode *node; 2978 GTypeClass *class = g_class; 2979 2980 g_return_if_fail (g_class != NULL); 2981 2982 node = lookup_type_node_I (class->g_type); 2983 if (node && node->is_classed && NODE_REFCOUNT (node)) 2984 type_data_unref_U (node, FALSE); 2985 else 2986 g_warning ("cannot unreference class of invalid (unclassed) type '%s'", 2987 type_descriptive_name_I (class->g_type)); 2988 } 2989 2990 /** 2991 * g_type_class_unref_uncached: (skip) 2992 * @g_class: (type GObject.TypeClass): a #GTypeClass structure to unref 2993 * 2994 * A variant of g_type_class_unref() for use in #GTypeClassCacheFunc 2995 * implementations. It unreferences a class without consulting the chain 2996 * of #GTypeClassCacheFuncs, avoiding the recursion which would occur 2997 * otherwise. 2998 */ 2999 void 3000 g_type_class_unref_uncached (gpointer g_class) 3001 { 3002 TypeNode *node; 3003 GTypeClass *class = g_class; 3004 3005 g_return_if_fail (g_class != NULL); 3006 3007 node = lookup_type_node_I (class->g_type); 3008 if (node && node->is_classed && NODE_REFCOUNT (node)) 3009 type_data_unref_U (node, TRUE); 3010 else 3011 g_warning ("cannot unreference class of invalid (unclassed) type '%s'", 3012 type_descriptive_name_I (class->g_type)); 3013 } 3014 3015 /** 3016 * g_type_class_peek: 3017 * @type: type ID of a classed type 3018 * 3019 * This function is essentially the same as g_type_class_ref(), 3020 * except that the classes reference count isn't incremented. 3021 * As a consequence, this function may return %NULL if the class 3022 * of the type passed in does not currently exist (hasn't been 3023 * referenced before). 3024 * 3025 * Returns: (type GObject.TypeClass) (transfer none): the #GTypeClass 3026 * structure for the given type ID or %NULL if the class does not 3027 * currently exist 3028 */ 3029 gpointer 3030 g_type_class_peek (GType type) 3031 { 3032 TypeNode *node; 3033 gpointer class; 3034 3035 node = lookup_type_node_I (type); 3036 if (node && node->is_classed && NODE_REFCOUNT (node) && 3037 g_atomic_int_get (&node->data->class.init_state) == INITIALIZED) 3038 /* ref_count _may_ be 0 */ 3039 class = node->data->class.class; 3040 else 3041 class = NULL; 3042 3043 return class; 3044 } 3045 3046 /** 3047 * g_type_class_peek_static: 3048 * @type: type ID of a classed type 3049 * 3050 * A more efficient version of g_type_class_peek() which works only for 3051 * static types. 3052 * 3053 * Returns: (type GObject.TypeClass) (transfer none): the #GTypeClass 3054 * structure for the given type ID or %NULL if the class does not 3055 * currently exist or is dynamically loaded 3056 * 3057 * Since: 2.4 3058 */ 3059 gpointer 3060 g_type_class_peek_static (GType type) 3061 { 3062 TypeNode *node; 3063 gpointer class; 3064 3065 node = lookup_type_node_I (type); 3066 if (node && node->is_classed && NODE_REFCOUNT (node) && 3067 /* peek only static types: */ node->plugin == NULL && 3068 g_atomic_int_get (&node->data->class.init_state) == INITIALIZED) 3069 /* ref_count _may_ be 0 */ 3070 class = node->data->class.class; 3071 else 3072 class = NULL; 3073 3074 return class; 3075 } 3076 3077 /** 3078 * g_type_class_peek_parent: 3079 * @g_class: (type GObject.TypeClass): the #GTypeClass structure to 3080 * retrieve the parent class for 3081 * 3082 * This is a convenience function often needed in class initializers. 3083 * It returns the class structure of the immediate parent type of the 3084 * class passed in. Since derived classes hold a reference count on 3085 * their parent classes as long as they are instantiated, the returned 3086 * class will always exist. 3087 * 3088 * This function is essentially equivalent to: 3089 * g_type_class_peek (g_type_parent (G_TYPE_FROM_CLASS (g_class))) 3090 * 3091 * Returns: (type GObject.TypeClass) (transfer none): the parent class 3092 * of @g_class 3093 */ 3094 gpointer 3095 g_type_class_peek_parent (gpointer g_class) 3096 { 3097 TypeNode *node; 3098 gpointer class = NULL; 3099 3100 g_return_val_if_fail (g_class != NULL, NULL); 3101 3102 node = lookup_type_node_I (G_TYPE_FROM_CLASS (g_class)); 3103 /* We used to acquire a read lock here. That is not necessary, since 3104 * parent->data->class.class is constant as long as the derived class 3105 * exists. 3106 */ 3107 if (node && node->is_classed && node->data && NODE_PARENT_TYPE (node)) 3108 { 3109 node = lookup_type_node_I (NODE_PARENT_TYPE (node)); 3110 class = node->data->class.class; 3111 } 3112 else if (NODE_PARENT_TYPE (node)) 3113 g_warning (G_STRLOC ": invalid class pointer '%p'", g_class); 3114 3115 return class; 3116 } 3117 3118 /** 3119 * g_type_interface_peek: 3120 * @instance_class: (type GObject.TypeClass): a #GTypeClass structure 3121 * @iface_type: an interface ID which this class conforms to 3122 * 3123 * Returns the #GTypeInterface structure of an interface to which the 3124 * passed in class conforms. 3125 * 3126 * Returns: (type GObject.TypeInterface) (transfer none): the #GTypeInterface 3127 * structure of @iface_type if implemented by @instance_class, %NULL 3128 * otherwise 3129 */ 3130 gpointer 3131 g_type_interface_peek (gpointer instance_class, 3132 GType iface_type) 3133 { 3134 TypeNode *node; 3135 TypeNode *iface; 3136 gpointer vtable = NULL; 3137 GTypeClass *class = instance_class; 3138 3139 g_return_val_if_fail (instance_class != NULL, NULL); 3140 3141 node = lookup_type_node_I (class->g_type); 3142 iface = lookup_type_node_I (iface_type); 3143 if (node && node->is_instantiatable && iface) 3144 type_lookup_iface_vtable_I (node, iface, &vtable); 3145 else 3146 g_warning (G_STRLOC ": invalid class pointer '%p'", class); 3147 3148 return vtable; 3149 } 3150 3151 /** 3152 * g_type_interface_peek_parent: 3153 * @g_iface: (type GObject.TypeInterface): a #GTypeInterface structure 3154 * 3155 * Returns the corresponding #GTypeInterface structure of the parent type 3156 * of the instance type to which @g_iface belongs. This is useful when 3157 * deriving the implementation of an interface from the parent type and 3158 * then possibly overriding some methods. 3159 * 3160 * Returns: (transfer none) (type GObject.TypeInterface): the 3161 * corresponding #GTypeInterface structure of the parent type of the 3162 * instance type to which @g_iface belongs, or %NULL if the parent 3163 * type doesn't conform to the interface 3164 */ 3165 gpointer 3166 g_type_interface_peek_parent (gpointer g_iface) 3167 { 3168 TypeNode *node; 3169 TypeNode *iface; 3170 gpointer vtable = NULL; 3171 GTypeInterface *iface_class = g_iface; 3172 3173 g_return_val_if_fail (g_iface != NULL, NULL); 3174 3175 iface = lookup_type_node_I (iface_class->g_type); 3176 node = lookup_type_node_I (iface_class->g_instance_type); 3177 if (node) 3178 node = lookup_type_node_I (NODE_PARENT_TYPE (node)); 3179 if (node && node->is_instantiatable && iface) 3180 type_lookup_iface_vtable_I (node, iface, &vtable); 3181 else if (node) 3182 g_warning (G_STRLOC ": invalid interface pointer '%p'", g_iface); 3183 3184 return vtable; 3185 } 3186 3187 /** 3188 * g_type_default_interface_ref: 3189 * @g_type: an interface type 3190 * 3191 * Increments the reference count for the interface type @g_type, 3192 * and returns the default interface vtable for the type. 3193 * 3194 * If the type is not currently in use, then the default vtable 3195 * for the type will be created and initalized by calling 3196 * the base interface init and default vtable init functions for 3197 * the type (the @base_init and @class_init members of #GTypeInfo). 3198 * Calling g_type_default_interface_ref() is useful when you 3199 * want to make sure that signals and properties for an interface 3200 * have been installed. 3201 * 3202 * Since: 2.4 3203 * 3204 * Returns: (type GObject.TypeInterface) (transfer none): the default 3205 * vtable for the interface; call g_type_default_interface_unref() 3206 * when you are done using the interface. 3207 */ 3208 gpointer 3209 g_type_default_interface_ref (GType g_type) 3210 { 3211 TypeNode *node; 3212 gpointer dflt_vtable; 3213 3214 G_WRITE_LOCK (&type_rw_lock); 3215 3216 node = lookup_type_node_I (g_type); 3217 if (!node || !NODE_IS_IFACE (node) || 3218 (node->data && NODE_REFCOUNT (node) == 0)) 3219 { 3220 G_WRITE_UNLOCK (&type_rw_lock); 3221 g_warning ("cannot retrieve default vtable for invalid or non-interface type '%s'", 3222 type_descriptive_name_I (g_type)); 3223 return NULL; 3224 } 3225 3226 if (!node->data || !node->data->iface.dflt_vtable) 3227 { 3228 G_WRITE_UNLOCK (&type_rw_lock); 3229 g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */ 3230 G_WRITE_LOCK (&type_rw_lock); 3231 node = lookup_type_node_I (g_type); 3232 type_data_ref_Wm (node); 3233 type_iface_ensure_dflt_vtable_Wm (node); 3234 g_rec_mutex_unlock (&class_init_rec_mutex); 3235 } 3236 else 3237 type_data_ref_Wm (node); /* ref_count >= 1 already */ 3238 3239 dflt_vtable = node->data->iface.dflt_vtable; 3240 G_WRITE_UNLOCK (&type_rw_lock); 3241 3242 return dflt_vtable; 3243 } 3244 3245 /** 3246 * g_type_default_interface_peek: 3247 * @g_type: an interface type 3248 * 3249 * If the interface type @g_type is currently in use, returns its 3250 * default interface vtable. 3251 * 3252 * Since: 2.4 3253 * 3254 * Returns: (type GObject.TypeInterface) (transfer none): the default 3255 * vtable for the interface, or %NULL if the type is not currently 3256 * in use 3257 */ 3258 gpointer 3259 g_type_default_interface_peek (GType g_type) 3260 { 3261 TypeNode *node; 3262 gpointer vtable; 3263 3264 node = lookup_type_node_I (g_type); 3265 if (node && NODE_IS_IFACE (node) && NODE_REFCOUNT (node)) 3266 vtable = node->data->iface.dflt_vtable; 3267 else 3268 vtable = NULL; 3269 3270 return vtable; 3271 } 3272 3273 /** 3274 * g_type_default_interface_unref: 3275 * @g_iface: (type GObject.TypeInterface): the default vtable 3276 * structure for a interface, as returned by g_type_default_interface_ref() 3277 * 3278 * Decrements the reference count for the type corresponding to the 3279 * interface default vtable @g_iface. If the type is dynamic, then 3280 * when no one is using the interface and all references have 3281 * been released, the finalize function for the interface's default 3282 * vtable (the @class_finalize member of #GTypeInfo) will be called. 3283 * 3284 * Since: 2.4 3285 */ 3286 void 3287 g_type_default_interface_unref (gpointer g_iface) 3288 { 3289 TypeNode *node; 3290 GTypeInterface *vtable = g_iface; 3291 3292 g_return_if_fail (g_iface != NULL); 3293 3294 node = lookup_type_node_I (vtable->g_type); 3295 if (node && NODE_IS_IFACE (node)) 3296 type_data_unref_U (node, FALSE); 3297 else 3298 g_warning ("cannot unreference invalid interface default vtable for '%s'", 3299 type_descriptive_name_I (vtable->g_type)); 3300 } 3301 3302 /** 3303 * g_type_name: 3304 * @type: type to return name for 3305 * 3306 * Get the unique name that is assigned to a type ID. Note that this 3307 * function (like all other GType API) cannot cope with invalid type 3308 * IDs. %G_TYPE_INVALID may be passed to this function, as may be any 3309 * other validly registered type ID, but randomized type IDs should 3310 * not be passed in and will most likely lead to a crash. 3311 * 3312 * Returns: static type name or %NULL 3313 */ 3314 const gchar * 3315 g_type_name (GType type) 3316 { 3317 TypeNode *node; 3318 3319 g_assert_type_system_initialized (); 3320 3321 node = lookup_type_node_I (type); 3322 3323 return node ? NODE_NAME (node) : NULL; 3324 } 3325 3326 /** 3327 * g_type_qname: 3328 * @type: type to return quark of type name for 3329 * 3330 * Get the corresponding quark of the type IDs name. 3331 * 3332 * Returns: the type names quark or 0 3333 */ 3334 GQuark 3335 g_type_qname (GType type) 3336 { 3337 TypeNode *node; 3338 3339 node = lookup_type_node_I (type); 3340 3341 return node ? node->qname : 0; 3342 } 3343 3344 /** 3345 * g_type_from_name: 3346 * @name: type name to lookup 3347 * 3348 * Lookup the type ID from a given type name, returning 0 if no type 3349 * has been registered under this name (this is the preferred method 3350 * to find out by name whether a specific type has been registered 3351 * yet). 3352 * 3353 * Returns: corresponding type ID or 0 3354 */ 3355 GType 3356 g_type_from_name (const gchar *name) 3357 { 3358 GType type = 0; 3359 3360 g_return_val_if_fail (name != NULL, 0); 3361 3362 G_READ_LOCK (&type_rw_lock); 3363 type = (GType) g_hash_table_lookup (static_type_nodes_ht, name); 3364 G_READ_UNLOCK (&type_rw_lock); 3365 3366 return type; 3367 } 3368 3369 /** 3370 * g_type_parent: 3371 * @type: the derived type 3372 * 3373 * Return the direct parent type of the passed in type. If the passed 3374 * in type has no parent, i.e. is a fundamental type, 0 is returned. 3375 * 3376 * Returns: the parent type 3377 */ 3378 GType 3379 g_type_parent (GType type) 3380 { 3381 TypeNode *node; 3382 3383 node = lookup_type_node_I (type); 3384 3385 return node ? NODE_PARENT_TYPE (node) : 0; 3386 } 3387 3388 /** 3389 * g_type_depth: 3390 * @type: a #GType 3391 * 3392 * Returns the length of the ancestry of the passed in type. This 3393 * includes the type itself, so that e.g. a fundamental type has depth 1. 3394 * 3395 * Returns: the depth of @type 3396 */ 3397 guint 3398 g_type_depth (GType type) 3399 { 3400 TypeNode *node; 3401 3402 node = lookup_type_node_I (type); 3403 3404 return node ? node->n_supers + 1 : 0; 3405 } 3406 3407 /** 3408 * g_type_next_base: 3409 * @leaf_type: descendant of @root_type and the type to be returned 3410 * @root_type: immediate parent of the returned type 3411 * 3412 * Given a @leaf_type and a @root_type which is contained in its 3413 * anchestry, return the type that @root_type is the immediate parent 3414 * of. In other words, this function determines the type that is 3415 * derived directly from @root_type which is also a base class of 3416 * @leaf_type. Given a root type and a leaf type, this function can 3417 * be used to determine the types and order in which the leaf type is 3418 * descended from the root type. 3419 * 3420 * Returns: immediate child of @root_type and anchestor of @leaf_type 3421 */ 3422 GType 3423 g_type_next_base (GType type, 3424 GType base_type) 3425 { 3426 GType atype = 0; 3427 TypeNode *node; 3428 3429 node = lookup_type_node_I (type); 3430 if (node) 3431 { 3432 TypeNode *base_node = lookup_type_node_I (base_type); 3433 3434 if (base_node && base_node->n_supers < node->n_supers) 3435 { 3436 guint n = node->n_supers - base_node->n_supers; 3437 3438 if (node->supers[n] == base_type) 3439 atype = node->supers[n - 1]; 3440 } 3441 } 3442 3443 return atype; 3444 } 3445 3446 static inline gboolean 3447 type_node_check_conformities_UorL (TypeNode *node, 3448 TypeNode *iface_node, 3449 /* support_inheritance */ 3450 gboolean support_interfaces, 3451 gboolean support_prerequisites, 3452 gboolean have_lock) 3453 { 3454 gboolean match; 3455 3456 if (/* support_inheritance && */ 3457 NODE_IS_ANCESTOR (iface_node, node)) 3458 return TRUE; 3459 3460 support_interfaces = support_interfaces && node->is_instantiatable && NODE_IS_IFACE (iface_node); 3461 support_prerequisites = support_prerequisites && NODE_IS_IFACE (node); 3462 match = FALSE; 3463 if (support_interfaces) 3464 { 3465 if (have_lock) 3466 { 3467 if (type_lookup_iface_entry_L (node, iface_node)) 3468 match = TRUE; 3469 } 3470 else 3471 { 3472 if (type_lookup_iface_vtable_I (node, iface_node, NULL)) 3473 match = TRUE; 3474 } 3475 } 3476 if (!match && 3477 support_prerequisites) 3478 { 3479 if (!have_lock) 3480 G_READ_LOCK (&type_rw_lock); 3481 if (support_prerequisites && type_lookup_prerequisite_L (node, NODE_TYPE (iface_node))) 3482 match = TRUE; 3483 if (!have_lock) 3484 G_READ_UNLOCK (&type_rw_lock); 3485 } 3486 return match; 3487 } 3488 3489 static gboolean 3490 type_node_is_a_L (TypeNode *node, 3491 TypeNode *iface_node) 3492 { 3493 return type_node_check_conformities_UorL (node, iface_node, TRUE, TRUE, TRUE); 3494 } 3495 3496 static inline gboolean 3497 type_node_conforms_to_U (TypeNode *node, 3498 TypeNode *iface_node, 3499 gboolean support_interfaces, 3500 gboolean support_prerequisites) 3501 { 3502 return type_node_check_conformities_UorL (node, iface_node, support_interfaces, support_prerequisites, FALSE); 3503 } 3504 3505 /** 3506 * g_type_is_a: 3507 * @type: type to check anchestry for 3508 * @is_a_type: possible anchestor of @type or interface that @type 3509 * could conform to 3510 * 3511 * If @is_a_type is a derivable type, check whether @type is a 3512 * descendant of @is_a_type. If @is_a_type is an interface, check 3513 * whether @type conforms to it. 3514 * 3515 * Returns: %TRUE if @type is a @is_a_type 3516 */ 3517 gboolean 3518 g_type_is_a (GType type, 3519 GType iface_type) 3520 { 3521 TypeNode *node, *iface_node; 3522 gboolean is_a; 3523 3524 if (type == iface_type) 3525 return TRUE; 3526 3527 node = lookup_type_node_I (type); 3528 iface_node = lookup_type_node_I (iface_type); 3529 is_a = node && iface_node && type_node_conforms_to_U (node, iface_node, TRUE, TRUE); 3530 3531 return is_a; 3532 } 3533 3534 /** 3535 * g_type_children: 3536 * @type: the parent type 3537 * @n_children: (out) (allow-none): location to store the length of 3538 * the returned array, or %NULL 3539 * 3540 * Return a newly allocated and 0-terminated array of type IDs, listing 3541 * the child types of @type. 3542 * 3543 * Returns: (array length=n_children) (transfer full): Newly allocated 3544 * and 0-terminated array of child types, free with g_free() 3545 */ 3546 GType* 3547 g_type_children (GType type, 3548 guint *n_children) 3549 { 3550 TypeNode *node; 3551 3552 node = lookup_type_node_I (type); 3553 if (node) 3554 { 3555 GType *children; 3556 3557 G_READ_LOCK (&type_rw_lock); /* ->children is relocatable */ 3558 children = g_new (GType, node->n_children + 1); 3559 memcpy (children, node->children, sizeof (GType) * node->n_children); 3560 children[node->n_children] = 0; 3561 3562 if (n_children) 3563 *n_children = node->n_children; 3564 G_READ_UNLOCK (&type_rw_lock); 3565 3566 return children; 3567 } 3568 else 3569 { 3570 if (n_children) 3571 *n_children = 0; 3572 3573 return NULL; 3574 } 3575 } 3576 3577 /** 3578 * g_type_interfaces: 3579 * @type: the type to list interface types for 3580 * @n_interfaces: (out) (allow-none): location to store the length of 3581 * the returned array, or %NULL 3582 * 3583 * Return a newly allocated and 0-terminated array of type IDs, listing 3584 * the interface types that @type conforms to. 3585 * 3586 * Returns: (array length=n_interfaces) (transfer full): Newly allocated 3587 * and 0-terminated array of interface types, free with g_free() 3588 */ 3589 GType* 3590 g_type_interfaces (GType type, 3591 guint *n_interfaces) 3592 { 3593 TypeNode *node; 3594 3595 node = lookup_type_node_I (type); 3596 if (node && node->is_instantiatable) 3597 { 3598 IFaceEntries *entries; 3599 GType *ifaces; 3600 guint i; 3601 3602 G_READ_LOCK (&type_rw_lock); 3603 entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node); 3604 if (entries) 3605 { 3606 ifaces = g_new (GType, IFACE_ENTRIES_N_ENTRIES (entries) + 1); 3607 for (i = 0; i < IFACE_ENTRIES_N_ENTRIES (entries); i++) 3608 ifaces[i] = entries->entry[i].iface_type; 3609 } 3610 else 3611 { 3612 ifaces = g_new (GType, 1); 3613 i = 0; 3614 } 3615 ifaces[i] = 0; 3616 3617 if (n_interfaces) 3618 *n_interfaces = i; 3619 G_READ_UNLOCK (&type_rw_lock); 3620 3621 return ifaces; 3622 } 3623 else 3624 { 3625 if (n_interfaces) 3626 *n_interfaces = 0; 3627 3628 return NULL; 3629 } 3630 } 3631 3632 typedef struct _QData QData; 3633 struct _GData 3634 { 3635 guint n_qdatas; 3636 QData *qdatas; 3637 }; 3638 struct _QData 3639 { 3640 GQuark quark; 3641 gpointer data; 3642 }; 3643 3644 static inline gpointer 3645 type_get_qdata_L (TypeNode *node, 3646 GQuark quark) 3647 { 3648 GData *gdata = node->global_gdata; 3649 3650 if (quark && gdata && gdata->n_qdatas) 3651 { 3652 QData *qdatas = gdata->qdatas - 1; 3653 guint n_qdatas = gdata->n_qdatas; 3654 3655 do 3656 { 3657 guint i; 3658 QData *check; 3659 3660 i = (n_qdatas + 1) / 2; 3661 check = qdatas + i; 3662 if (quark == check->quark) 3663 return check->data; 3664 else if (quark > check->quark) 3665 { 3666 n_qdatas -= i; 3667 qdatas = check; 3668 } 3669 else /* if (quark < check->quark) */ 3670 n_qdatas = i - 1; 3671 } 3672 while (n_qdatas); 3673 } 3674 return NULL; 3675 } 3676 3677 /** 3678 * g_type_get_qdata: 3679 * @type: a #GType 3680 * @quark: a #GQuark id to identify the data 3681 * 3682 * Obtains data which has previously been attached to @type 3683 * with g_type_set_qdata(). 3684 * 3685 * Note that this does not take subtyping into account; data 3686 * attached to one type with g_type_set_qdata() cannot 3687 * be retrieved from a subtype using g_type_get_qdata(). 3688 * 3689 * Returns: (transfer none): the data, or %NULL if no data was found 3690 */ 3691 gpointer 3692 g_type_get_qdata (GType type, 3693 GQuark quark) 3694 { 3695 TypeNode *node; 3696 gpointer data; 3697 3698 node = lookup_type_node_I (type); 3699 if (node) 3700 { 3701 G_READ_LOCK (&type_rw_lock); 3702 data = type_get_qdata_L (node, quark); 3703 G_READ_UNLOCK (&type_rw_lock); 3704 } 3705 else 3706 { 3707 g_return_val_if_fail (node != NULL, NULL); 3708 data = NULL; 3709 } 3710 return data; 3711 } 3712 3713 static inline void 3714 type_set_qdata_W (TypeNode *node, 3715 GQuark quark, 3716 gpointer data) 3717 { 3718 GData *gdata; 3719 QData *qdata; 3720 guint i; 3721 3722 /* setup qdata list if necessary */ 3723 if (!node->global_gdata) 3724 node->global_gdata = g_new0 (GData, 1); 3725 gdata = node->global_gdata; 3726 3727 /* try resetting old data */ 3728 qdata = gdata->qdatas; 3729 for (i = 0; i < gdata->n_qdatas; i++) 3730 if (qdata[i].quark == quark) 3731 { 3732 qdata[i].data = data; 3733 return; 3734 } 3735 3736 /* add new entry */ 3737 gdata->n_qdatas++; 3738 gdata->qdatas = g_renew (QData, gdata->qdatas, gdata->n_qdatas); 3739 qdata = gdata->qdatas; 3740 for (i = 0; i < gdata->n_qdatas - 1; i++) 3741 if (qdata[i].quark > quark) 3742 break; 3743 memmove (qdata + i + 1, qdata + i, sizeof (qdata[0]) * (gdata->n_qdatas - i - 1)); 3744 qdata[i].quark = quark; 3745 qdata[i].data = data; 3746 } 3747 3748 /** 3749 * g_type_set_qdata: 3750 * @type: a #GType 3751 * @quark: a #GQuark id to identify the data 3752 * @data: the data 3753 * 3754 * Attaches arbitrary data to a type. 3755 */ 3756 void 3757 g_type_set_qdata (GType type, 3758 GQuark quark, 3759 gpointer data) 3760 { 3761 TypeNode *node; 3762 3763 g_return_if_fail (quark != 0); 3764 3765 node = lookup_type_node_I (type); 3766 if (node) 3767 { 3768 G_WRITE_LOCK (&type_rw_lock); 3769 type_set_qdata_W (node, quark, data); 3770 G_WRITE_UNLOCK (&type_rw_lock); 3771 } 3772 else 3773 g_return_if_fail (node != NULL); 3774 } 3775 3776 static void 3777 type_add_flags_W (TypeNode *node, 3778 GTypeFlags flags) 3779 { 3780 guint dflags; 3781 3782 g_return_if_fail ((flags & ~TYPE_FLAG_MASK) == 0); 3783 g_return_if_fail (node != NULL); 3784 3785 if ((flags & TYPE_FLAG_MASK) && node->is_classed && node->data && node->data->class.class) 3786 g_warning ("tagging type '%s' as abstract after class initialization", NODE_NAME (node)); 3787 dflags = GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags)); 3788 dflags |= flags; 3789 type_set_qdata_W (node, static_quark_type_flags, GUINT_TO_POINTER (dflags)); 3790 } 3791 3792 /** 3793 * g_type_query: 3794 * @type: #GType of a static, classed type 3795 * @query: (out caller-allocates): a user provided structure that is 3796 * filled in with constant values upon success 3797 * 3798 * Queries the type system for information about a specific type. 3799 * This function will fill in a user-provided structure to hold 3800 * type-specific information. If an invalid #GType is passed in, the 3801 * @type member of the #GTypeQuery is 0. All members filled into the 3802 * #GTypeQuery structure should be considered constant and have to be 3803 * left untouched. 3804 */ 3805 void 3806 g_type_query (GType type, 3807 GTypeQuery *query) 3808 { 3809 TypeNode *node; 3810 3811 g_return_if_fail (query != NULL); 3812 3813 /* if node is not static and classed, we won't allow query */ 3814 query->type = 0; 3815 node = lookup_type_node_I (type); 3816 if (node && node->is_classed && !node->plugin) 3817 { 3818 /* type is classed and probably even instantiatable */ 3819 G_READ_LOCK (&type_rw_lock); 3820 if (node->data) /* type is static or referenced */ 3821 { 3822 query->type = NODE_TYPE (node); 3823 query->type_name = NODE_NAME (node); 3824 query->class_size = node->data->class.class_size; 3825 query->instance_size = node->is_instantiatable ? node->data->instance.instance_size : 0; 3826 } 3827 G_READ_UNLOCK (&type_rw_lock); 3828 } 3829 } 3830 3831 3832 /* --- implementation details --- */ 3833 gboolean 3834 g_type_test_flags (GType type, 3835 guint flags) 3836 { 3837 TypeNode *node; 3838 gboolean result = FALSE; 3839 3840 node = lookup_type_node_I (type); 3841 if (node) 3842 { 3843 guint fflags = flags & TYPE_FUNDAMENTAL_FLAG_MASK; 3844 guint tflags = flags & TYPE_FLAG_MASK; 3845 3846 if (fflags) 3847 { 3848 GTypeFundamentalInfo *finfo = type_node_fundamental_info_I (node); 3849 3850 fflags = (finfo->type_flags & fflags) == fflags; 3851 } 3852 else 3853 fflags = TRUE; 3854 3855 if (tflags) 3856 { 3857 G_READ_LOCK (&type_rw_lock); 3858 tflags = (tflags & GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags))) == tflags; 3859 G_READ_UNLOCK (&type_rw_lock); 3860 } 3861 else 3862 tflags = TRUE; 3863 3864 result = tflags && fflags; 3865 } 3866 3867 return result; 3868 } 3869 3870 /** 3871 * g_type_get_plugin: 3872 * @type: #GType to retrieve the plugin for 3873 * 3874 * Returns the #GTypePlugin structure for @type. 3875 * 3876 * Returns: (transfer none): the corresponding plugin 3877 * if @type is a dynamic type, %NULL otherwise 3878 */ 3879 GTypePlugin* 3880 g_type_get_plugin (GType type) 3881 { 3882 TypeNode *node; 3883 3884 node = lookup_type_node_I (type); 3885 3886 return node ? node->plugin : NULL; 3887 } 3888 3889 /** 3890 * g_type_interface_get_plugin: 3891 * @instance_type: #GType of an instantiatable type 3892 * @interface_type: #GType of an interface type 3893 * 3894 * Returns the #GTypePlugin structure for the dynamic interface 3895 * @interface_type which has been added to @instance_type, or %NULL 3896 * if @interface_type has not been added to @instance_type or does 3897 * not have a #GTypePlugin structure. See g_type_add_interface_dynamic(). 3898 * 3899 * Returns: (transfer none): the #GTypePlugin for the dynamic 3900 * interface @interface_type of @instance_type 3901 */ 3902 GTypePlugin* 3903 g_type_interface_get_plugin (GType instance_type, 3904 GType interface_type) 3905 { 3906 TypeNode *node; 3907 TypeNode *iface; 3908 3909 g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface_type), NULL); /* G_TYPE_IS_INTERFACE() is an external call: _U */ 3910 3911 node = lookup_type_node_I (instance_type); 3912 iface = lookup_type_node_I (interface_type); 3913 if (node && iface) 3914 { 3915 IFaceHolder *iholder; 3916 GTypePlugin *plugin; 3917 3918 G_READ_LOCK (&type_rw_lock); 3919 3920 iholder = iface_node_get_holders_L (iface); 3921 while (iholder && iholder->instance_type != instance_type) 3922 iholder = iholder->next; 3923 plugin = iholder ? iholder->plugin : NULL; 3924 3925 G_READ_UNLOCK (&type_rw_lock); 3926 3927 return plugin; 3928 } 3929 3930 g_return_val_if_fail (node == NULL, NULL); 3931 g_return_val_if_fail (iface == NULL, NULL); 3932 3933 g_warning (G_STRLOC ": attempt to look up plugin for invalid instance/interface type pair."); 3934 3935 return NULL; 3936 } 3937 3938 /** 3939 * g_type_fundamental_next: 3940 * 3941 * Returns the next free fundamental type id which can be used to 3942 * register a new fundamental type with g_type_register_fundamental(). 3943 * The returned type ID represents the highest currently registered 3944 * fundamental type identifier. 3945 * 3946 * Returns: the next available fundamental type ID to be registered, 3947 * or 0 if the type system ran out of fundamental type IDs 3948 */ 3949 GType 3950 g_type_fundamental_next (void) 3951 { 3952 GType type; 3953 3954 G_READ_LOCK (&type_rw_lock); 3955 type = static_fundamental_next; 3956 G_READ_UNLOCK (&type_rw_lock); 3957 type = G_TYPE_MAKE_FUNDAMENTAL (type); 3958 return type <= G_TYPE_FUNDAMENTAL_MAX ? type : 0; 3959 } 3960 3961 /** 3962 * g_type_fundamental: 3963 * @type_id: valid type ID 3964 * 3965 * Internal function, used to extract the fundamental type ID portion. 3966 * Use G_TYPE_FUNDAMENTAL() instead. 3967 * 3968 * Returns: fundamental type ID 3969 */ 3970 GType 3971 g_type_fundamental (GType type_id) 3972 { 3973 TypeNode *node = lookup_type_node_I (type_id); 3974 3975 return node ? NODE_FUNDAMENTAL_TYPE (node) : 0; 3976 } 3977 3978 gboolean 3979 g_type_check_instance_is_a (GTypeInstance *type_instance, 3980 GType iface_type) 3981 { 3982 TypeNode *node, *iface; 3983 gboolean check; 3984 3985 if (!type_instance || !type_instance->g_class) 3986 return FALSE; 3987 3988 node = lookup_type_node_I (type_instance->g_class->g_type); 3989 iface = lookup_type_node_I (iface_type); 3990 check = node && node->is_instantiatable && iface && type_node_conforms_to_U (node, iface, TRUE, FALSE); 3991 3992 return check; 3993 } 3994 3995 gboolean 3996 g_type_check_instance_is_fundamentally_a (GTypeInstance *type_instance, 3997 GType fundamental_type) 3998 { 3999 TypeNode *node; 4000 if (!type_instance || !type_instance->g_class) 4001 return FALSE; 4002 node = lookup_type_node_I (type_instance->g_class->g_type); 4003 return node && (NODE_FUNDAMENTAL_TYPE(node) == fundamental_type); 4004 } 4005 4006 gboolean 4007 g_type_check_class_is_a (GTypeClass *type_class, 4008 GType is_a_type) 4009 { 4010 TypeNode *node, *iface; 4011 gboolean check; 4012 4013 if (!type_class) 4014 return FALSE; 4015 4016 node = lookup_type_node_I (type_class->g_type); 4017 iface = lookup_type_node_I (is_a_type); 4018 check = node && node->is_classed && iface && type_node_conforms_to_U (node, iface, FALSE, FALSE); 4019 4020 return check; 4021 } 4022 4023 GTypeInstance* 4024 g_type_check_instance_cast (GTypeInstance *type_instance, 4025 GType iface_type) 4026 { 4027 if (type_instance) 4028 { 4029 if (type_instance->g_class) 4030 { 4031 TypeNode *node, *iface; 4032 gboolean is_instantiatable, check; 4033 4034 node = lookup_type_node_I (type_instance->g_class->g_type); 4035 is_instantiatable = node && node->is_instantiatable; 4036 iface = lookup_type_node_I (iface_type); 4037 check = is_instantiatable && iface && type_node_conforms_to_U (node, iface, TRUE, FALSE); 4038 if (check) 4039 return type_instance; 4040 4041 if (is_instantiatable) 4042 g_warning ("invalid cast from '%s' to '%s'", 4043 type_descriptive_name_I (type_instance->g_class->g_type), 4044 type_descriptive_name_I (iface_type)); 4045 else 4046 g_warning ("invalid uninstantiatable type '%s' in cast to '%s'", 4047 type_descriptive_name_I (type_instance->g_class->g_type), 4048 type_descriptive_name_I (iface_type)); 4049 } 4050 else 4051 g_warning ("invalid unclassed pointer in cast to '%s'", 4052 type_descriptive_name_I (iface_type)); 4053 } 4054 4055 return type_instance; 4056 } 4057 4058 GTypeClass* 4059 g_type_check_class_cast (GTypeClass *type_class, 4060 GType is_a_type) 4061 { 4062 if (type_class) 4063 { 4064 TypeNode *node, *iface; 4065 gboolean is_classed, check; 4066 4067 node = lookup_type_node_I (type_class->g_type); 4068 is_classed = node && node->is_classed; 4069 iface = lookup_type_node_I (is_a_type); 4070 check = is_classed && iface && type_node_conforms_to_U (node, iface, FALSE, FALSE); 4071 if (check) 4072 return type_class; 4073 4074 if (is_classed) 4075 g_warning ("invalid class cast from '%s' to '%s'", 4076 type_descriptive_name_I (type_class->g_type), 4077 type_descriptive_name_I (is_a_type)); 4078 else 4079 g_warning ("invalid unclassed type '%s' in class cast to '%s'", 4080 type_descriptive_name_I (type_class->g_type), 4081 type_descriptive_name_I (is_a_type)); 4082 } 4083 else 4084 g_warning ("invalid class cast from (NULL) pointer to '%s'", 4085 type_descriptive_name_I (is_a_type)); 4086 return type_class; 4087 } 4088 4089 /** 4090 * g_type_check_instance: 4091 * @instance: a valid #GTypeInstance structure 4092 * 4093 * Private helper function to aid implementation of the 4094 * G_TYPE_CHECK_INSTANCE() macro. 4095 * 4096 * Returns: %TRUE if @instance is valid, %FALSE otherwise 4097 */ 4098 gboolean 4099 g_type_check_instance (GTypeInstance *type_instance) 4100 { 4101 /* this function is just here to make the signal system 4102 * conveniently elaborated on instance checks 4103 */ 4104 if (type_instance) 4105 { 4106 if (type_instance->g_class) 4107 { 4108 TypeNode *node = lookup_type_node_I (type_instance->g_class->g_type); 4109 4110 if (node && node->is_instantiatable) 4111 return TRUE; 4112 4113 g_warning ("instance of invalid non-instantiatable type '%s'", 4114 type_descriptive_name_I (type_instance->g_class->g_type)); 4115 } 4116 else 4117 g_warning ("instance with invalid (NULL) class pointer"); 4118 } 4119 else 4120 g_warning ("invalid (NULL) pointer instance"); 4121 4122 return FALSE; 4123 } 4124 4125 static inline gboolean 4126 type_check_is_value_type_U (GType type) 4127 { 4128 GTypeFlags tflags = G_TYPE_FLAG_VALUE_ABSTRACT; 4129 TypeNode *node; 4130 4131 /* common path speed up */ 4132 node = lookup_type_node_I (type); 4133 if (node && node->mutatable_check_cache) 4134 return TRUE; 4135 4136 G_READ_LOCK (&type_rw_lock); 4137 restart_check: 4138 if (node) 4139 { 4140 if (node->data && NODE_REFCOUNT (node) > 0 && 4141 node->data->common.value_table->value_init) 4142 tflags = GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags)); 4143 else if (NODE_IS_IFACE (node)) 4144 { 4145 guint i; 4146 4147 for (i = 0; i < IFACE_NODE_N_PREREQUISITES (node); i++) 4148 { 4149 GType prtype = IFACE_NODE_PREREQUISITES (node)[i]; 4150 TypeNode *prnode = lookup_type_node_I (prtype); 4151 4152 if (prnode->is_instantiatable) 4153 { 4154 type = prtype; 4155 node = lookup_type_node_I (type); 4156 goto restart_check; 4157 } 4158 } 4159 } 4160 } 4161 G_READ_UNLOCK (&type_rw_lock); 4162 4163 return !(tflags & G_TYPE_FLAG_VALUE_ABSTRACT); 4164 } 4165 4166 gboolean 4167 g_type_check_is_value_type (GType type) 4168 { 4169 return type_check_is_value_type_U (type); 4170 } 4171 4172 gboolean 4173 g_type_check_value (GValue *value) 4174 { 4175 return value && type_check_is_value_type_U (value->g_type); 4176 } 4177 4178 gboolean 4179 g_type_check_value_holds (GValue *value, 4180 GType type) 4181 { 4182 return value && type_check_is_value_type_U (value->g_type) && g_type_is_a (value->g_type, type); 4183 } 4184 4185 /** 4186 * g_type_value_table_peek: (skip) 4187 * @type: a #GType 4188 * 4189 * Returns the location of the #GTypeValueTable associated with @type. 4190 * 4191 * Note that this function should only be used from source code 4192 * that implements or has internal knowledge of the implementation of 4193 * @type. 4194 * 4195 * Returns: location of the #GTypeValueTable associated with @type or 4196 * %NULL if there is no #GTypeValueTable associated with @type 4197 */ 4198 GTypeValueTable* 4199 g_type_value_table_peek (GType type) 4200 { 4201 GTypeValueTable *vtable = NULL; 4202 TypeNode *node = lookup_type_node_I (type); 4203 gboolean has_refed_data, has_table; 4204 4205 if (node && NODE_REFCOUNT (node) && node->mutatable_check_cache) 4206 return node->data->common.value_table; 4207 4208 G_READ_LOCK (&type_rw_lock); 4209 4210 restart_table_peek: 4211 has_refed_data = node && node->data && NODE_REFCOUNT (node) > 0; 4212 has_table = has_refed_data && node->data->common.value_table->value_init; 4213 if (has_refed_data) 4214 { 4215 if (has_table) 4216 vtable = node->data->common.value_table; 4217 else if (NODE_IS_IFACE (node)) 4218 { 4219 guint i; 4220 4221 for (i = 0; i < IFACE_NODE_N_PREREQUISITES (node); i++) 4222 { 4223 GType prtype = IFACE_NODE_PREREQUISITES (node)[i]; 4224 TypeNode *prnode = lookup_type_node_I (prtype); 4225 4226 if (prnode->is_instantiatable) 4227 { 4228 type = prtype; 4229 node = lookup_type_node_I (type); 4230 goto restart_table_peek; 4231 } 4232 } 4233 } 4234 } 4235 4236 G_READ_UNLOCK (&type_rw_lock); 4237 4238 if (vtable) 4239 return vtable; 4240 4241 if (!node) 4242 g_warning (G_STRLOC ": type id '%" G_GSIZE_FORMAT "' is invalid", type); 4243 if (!has_refed_data) 4244 g_warning ("can't peek value table for type '%s' which is not currently referenced", 4245 type_descriptive_name_I (type)); 4246 4247 return NULL; 4248 } 4249 4250 const gchar * 4251 g_type_name_from_instance (GTypeInstance *instance) 4252 { 4253 if (!instance) 4254 return "<NULL-instance>"; 4255 else 4256 return g_type_name_from_class (instance->g_class); 4257 } 4258 4259 const gchar * 4260 g_type_name_from_class (GTypeClass *g_class) 4261 { 4262 if (!g_class) 4263 return "<NULL-class>"; 4264 else 4265 return g_type_name (g_class->g_type); 4266 } 4267 4268 4269 /* --- private api for gboxed.c --- */ 4270 gpointer 4271 _g_type_boxed_copy (GType type, gpointer value) 4272 { 4273 TypeNode *node = lookup_type_node_I (type); 4274 4275 return node->data->boxed.copy_func (value); 4276 } 4277 4278 void 4279 _g_type_boxed_free (GType type, gpointer value) 4280 { 4281 TypeNode *node = lookup_type_node_I (type); 4282 4283 node->data->boxed.free_func (value); 4284 } 4285 4286 void 4287 _g_type_boxed_init (GType type, 4288 GBoxedCopyFunc copy_func, 4289 GBoxedFreeFunc free_func) 4290 { 4291 TypeNode *node = lookup_type_node_I (type); 4292 4293 node->data->boxed.copy_func = copy_func; 4294 node->data->boxed.free_func = free_func; 4295 } 4296 4297 /* --- initialization --- */ 4298 /** 4299 * g_type_init_with_debug_flags: 4300 * @debug_flags: bitwise combination of #GTypeDebugFlags values for 4301 * debugging purposes 4302 * 4303 * This function used to initialise the type system with debugging 4304 * flags. Since GLib 2.36, the type system is initialised automatically 4305 * and this function does nothing. 4306 * 4307 * If you need to enable debugging features, use the GOBJECT_DEBUG 4308 * environment variable. 4309 * 4310 * Deprecated: 2.36: the type system is now initialised automatically 4311 */ 4312 void 4313 g_type_init_with_debug_flags (GTypeDebugFlags debug_flags) 4314 { 4315 g_assert_type_system_initialized (); 4316 4317 if (debug_flags) 4318 g_message ("g_type_init_with_debug_flags() is no longer supported. Use the GOBJECT_DEBUG environment variable."); 4319 } 4320 4321 /** 4322 * g_type_init: 4323 * 4324 * This function used to initialise the type system. Since GLib 2.36, 4325 * the type system is initialised automatically and this function does 4326 * nothing. 4327 * 4328 * Deprecated: 2.36: the type system is now initialised automatically 4329 */ 4330 #if !(defined(GSTREAMER_LITE) && defined(G_OS_WIN32)) 4331 void 4332 g_type_init (void) 4333 { 4334 g_assert_type_system_initialized (); 4335 } 4336 #endif // GSTREAMER_LITE 4337 4338 #if defined(GSTREAMER_LITE) && defined(G_OS_WIN32) 4339 // We cannot due static initialization, since it will crash due to 4340 // threading system is not initialized yet. 4341 static void gobject_init_ctor (void); 4342 void 4343 g_type_init (void) 4344 { 4345 gobject_init_ctor (); 4346 } 4347 #else GSTREAMER_LITE 4348 #if defined (G_HAS_CONSTRUCTORS) 4349 #ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 4350 #pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(gobject_init_ctor) 4351 #endif 4352 G_DEFINE_CONSTRUCTOR(gobject_init_ctor) 4353 #else 4354 # error Your platform/compiler is missing constructor support 4355 #endif 4356 #endif // GSTREAMER_LITE 4357 4358 static void 4359 gobject_init_ctor (void) 4360 { 4361 const gchar *env_string; 4362 GTypeInfo info; 4363 TypeNode *node; 4364 GType type; 4365 4366 G_WRITE_LOCK (&type_rw_lock); 4367 4368 /* setup GObject library wide debugging flags */ 4369 env_string = g_getenv ("GOBJECT_DEBUG"); 4370 if (env_string != NULL) 4371 { 4372 GDebugKey debug_keys[] = { 4373 { "objects", G_TYPE_DEBUG_OBJECTS }, 4374 { "signals", G_TYPE_DEBUG_SIGNALS }, 4375 }; 4376 4377 _g_type_debug_flags = g_parse_debug_string (env_string, debug_keys, G_N_ELEMENTS (debug_keys)); 4378 } 4379 4380 /* quarks */ 4381 static_quark_type_flags = g_quark_from_static_string ("-g-type-private--GTypeFlags"); 4382 static_quark_iface_holder = g_quark_from_static_string ("-g-type-private--IFaceHolder"); 4383 static_quark_dependants_array = g_quark_from_static_string ("-g-type-private--dependants-array"); 4384 4385 /* type qname hash table */ 4386 static_type_nodes_ht = g_hash_table_new (g_str_hash, g_str_equal); 4387 4388 /* invalid type G_TYPE_INVALID (0) 4389 */ 4390 static_fundamental_type_nodes[0] = NULL; 4391 4392 /* void type G_TYPE_NONE 4393 */ 4394 node = type_node_fundamental_new_W (G_TYPE_NONE, g_intern_static_string ("void"), 0); 4395 type = NODE_TYPE (node); 4396 g_assert (type == G_TYPE_NONE); 4397 4398 /* interface fundamental type G_TYPE_INTERFACE (!classed) 4399 */ 4400 memset (&info, 0, sizeof (info)); 4401 node = type_node_fundamental_new_W (G_TYPE_INTERFACE, g_intern_static_string ("GInterface"), G_TYPE_FLAG_DERIVABLE); 4402 type = NODE_TYPE (node); 4403 type_data_make_W (node, &info, NULL); 4404 g_assert (type == G_TYPE_INTERFACE); 4405 4406 G_WRITE_UNLOCK (&type_rw_lock); 4407 4408 _g_value_c_init (); 4409 4410 /* G_TYPE_TYPE_PLUGIN 4411 */ 4412 g_type_ensure (g_type_plugin_get_type ()); 4413 4414 /* G_TYPE_* value types 4415 */ 4416 _g_value_types_init (); 4417 4418 /* G_TYPE_ENUM & G_TYPE_FLAGS 4419 */ 4420 _g_enum_types_init (); 4421 4422 /* G_TYPE_BOXED 4423 */ 4424 _g_boxed_type_init (); 4425 4426 /* G_TYPE_PARAM 4427 */ 4428 _g_param_type_init (); 4429 4430 /* G_TYPE_OBJECT 4431 */ 4432 _g_object_type_init (); 4433 4434 /* G_TYPE_PARAM_* pspec types 4435 */ 4436 _g_param_spec_types_init (); 4437 4438 /* Value Transformations 4439 */ 4440 _g_value_transforms_init (); 4441 4442 /* Signal system 4443 */ 4444 _g_signal_init (); 4445 } 4446 4447 /** 4448 * g_type_class_add_private: 4449 * @g_class: class structure for an instantiatable type 4450 * @private_size: size of private structure 4451 * 4452 * Registers a private structure for an instantiatable type. 4453 * 4454 * When an object is allocated, the private structures for 4455 * the type and all of its parent types are allocated 4456 * sequentially in the same memory block as the public 4457 * structures, and are zero-filled. 4458 * 4459 * Note that the accumulated size of the private structures of 4460 * a type and all its parent types cannot exceed 64 KiB. 4461 * 4462 * This function should be called in the type's class_init() function. 4463 * The private structure can be retrieved using the 4464 * G_TYPE_INSTANCE_GET_PRIVATE() macro. 4465 * 4466 * The following example shows attaching a private structure 4467 * MyObjectPrivate to an object MyObject defined in the standard 4468 * GObject fashion in the type's class_init() function. 4469 * 4470 * Note the use of a structure member "priv" to avoid the overhead 4471 * of repeatedly calling MY_OBJECT_GET_PRIVATE(). 4472 * 4473 * |[<!-- language="C" --> 4474 * typedef struct _MyObject MyObject; 4475 * typedef struct _MyObjectPrivate MyObjectPrivate; 4476 * 4477 * struct _MyObject { 4478 * GObject parent; 4479 * 4480 * MyObjectPrivate *priv; 4481 * }; 4482 * 4483 * struct _MyObjectPrivate { 4484 * int some_field; 4485 * }; 4486 * 4487 * static void 4488 * my_object_class_init (MyObjectClass *klass) 4489 * { 4490 * g_type_class_add_private (klass, sizeof (MyObjectPrivate)); 4491 * } 4492 * 4493 * static void 4494 * my_object_init (MyObject *my_object) 4495 * { 4496 * my_object->priv = G_TYPE_INSTANCE_GET_PRIVATE (my_object, 4497 * MY_TYPE_OBJECT, 4498 * MyObjectPrivate); 4499 * // my_object->priv->some_field will be automatically initialised to 0 4500 * } 4501 * 4502 * static int 4503 * my_object_get_some_field (MyObject *my_object) 4504 * { 4505 * MyObjectPrivate *priv; 4506 * 4507 * g_return_val_if_fail (MY_IS_OBJECT (my_object), 0); 4508 * 4509 * priv = my_object->priv; 4510 * 4511 * return priv->some_field; 4512 * } 4513 * ]| 4514 * 4515 * Since: 2.4 4516 */ 4517 void 4518 g_type_class_add_private (gpointer g_class, 4519 gsize private_size) 4520 { 4521 GType instance_type = ((GTypeClass *)g_class)->g_type; 4522 TypeNode *node = lookup_type_node_I (instance_type); 4523 4524 g_return_if_fail (private_size > 0); 4525 g_return_if_fail (private_size <= 0xffff); 4526 4527 if (!node || !node->is_instantiatable || !node->data || node->data->class.class != g_class) 4528 { 4529 g_warning ("cannot add private field to invalid (non-instantiatable) type '%s'", 4530 type_descriptive_name_I (instance_type)); 4531 return; 4532 } 4533 4534 if (NODE_PARENT_TYPE (node)) 4535 { 4536 TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); 4537 if (node->data->instance.private_size != pnode->data->instance.private_size) 4538 { 4539 g_warning ("g_type_class_add_private() called multiple times for the same type"); 4540 return; 4541 } 4542 } 4543 4544 G_WRITE_LOCK (&type_rw_lock); 4545 4546 private_size = ALIGN_STRUCT (node->data->instance.private_size + private_size); 4547 g_assert (private_size <= 0xffff); 4548 node->data->instance.private_size = private_size; 4549 4550 G_WRITE_UNLOCK (&type_rw_lock); 4551 } 4552 4553 /* semi-private, called only by the G_ADD_PRIVATE macro */ 4554 gint 4555 g_type_add_instance_private (GType class_gtype, 4556 gsize private_size) 4557 { 4558 TypeNode *node = lookup_type_node_I (class_gtype); 4559 4560 g_return_val_if_fail (private_size > 0, 0); 4561 g_return_val_if_fail (private_size <= 0xffff, 0); 4562 4563 if (!node || !node->is_classed || !node->is_instantiatable || !node->data) 4564 { 4565 g_warning ("cannot add private field to invalid (non-instantiatable) type '%s'", 4566 type_descriptive_name_I (class_gtype)); 4567 return 0; 4568 } 4569 4570 if (node->plugin != NULL) 4571 { 4572 g_warning ("cannot use g_type_add_instance_private() with dynamic type '%s'", 4573 type_descriptive_name_I (class_gtype)); 4574 return 0; 4575 } 4576 4577 /* in the future, we want to register the private data size of a type 4578 * directly from the get_type() implementation so that we can take full 4579 * advantage of the type definition macros that we already have. 4580 * 4581 * unfortunately, this does not behave correctly if a class in the middle 4582 * of the type hierarchy uses the "old style" of private data registration 4583 * from the class_init() implementation, as the private data offset is not 4584 * going to be known until the full class hierarchy is initialized. 4585 * 4586 * in order to transition our code to the Glorious New Futureā¢, we proceed 4587 * with a two-step implementation: first, we provide this new function to 4588 * register the private data size in the get_type() implementation and we 4589 * hide it behind a macro. the function will return the private size, instead 4590 * of the offset, which will be stored inside a static variable defined by 4591 * the G_DEFINE_TYPE_EXTENDED macro. the G_DEFINE_TYPE_EXTENDED macro will 4592 * check the variable and call g_type_class_add_instance_private(), which 4593 * will use the data size and actually register the private data, then 4594 * return the computed offset of the private data, which will be stored 4595 * inside the static variable, so we can use it to retrieve the pointer 4596 * to the private data structure. 4597 * 4598 * once all our code has been migrated to the new idiomatic form of private 4599 * data registration, we will change the g_type_add_instance_private() 4600 * function to actually perform the registration and return the offset 4601 * of the private data; g_type_class_add_instance_private() already checks 4602 * if the passed argument is negative (meaning that it's an offset in the 4603 * GTypeInstance allocation) and becomes a no-op if that's the case. this 4604 * should make the migration fully transparent even if we're effectively 4605 * copying this macro into everybody's code. 4606 */ 4607 return private_size; 4608 } 4609 4610 /* semi-private function, should only be used by G_DEFINE_TYPE_EXTENDED */ 4611 void 4612 g_type_class_adjust_private_offset (gpointer g_class, 4613 gint *private_size_or_offset) 4614 { 4615 GType class_gtype = ((GTypeClass *) g_class)->g_type; 4616 TypeNode *node = lookup_type_node_I (class_gtype); 4617 gssize private_size; 4618 4619 g_return_if_fail (private_size_or_offset != NULL); 4620 4621 /* if we have been passed the offset instead of the private data size, 4622 * then we consider this as a no-op, and just return the value. see the 4623 * comment in g_type_add_instance_private() for the full explanation. 4624 */ 4625 if (*private_size_or_offset > 0) 4626 g_return_if_fail (*private_size_or_offset <= 0xffff); 4627 else 4628 return; 4629 4630 if (!node || !node->is_classed || !node->is_instantiatable || !node->data) 4631 { 4632 g_warning ("cannot add private field to invalid (non-instantiatable) type '%s'", 4633 type_descriptive_name_I (class_gtype)); 4634 *private_size_or_offset = 0; 4635 return; 4636 } 4637 4638 if (NODE_PARENT_TYPE (node)) 4639 { 4640 TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); 4641 if (node->data->instance.private_size != pnode->data->instance.private_size) 4642 { 4643 g_warning ("g_type_add_instance_private() called multiple times for the same type"); 4644 *private_size_or_offset = 0; 4645 return; 4646 } 4647 } 4648 4649 G_WRITE_LOCK (&type_rw_lock); 4650 4651 private_size = ALIGN_STRUCT (node->data->instance.private_size + *private_size_or_offset); 4652 g_assert (private_size <= 0xffff); 4653 node->data->instance.private_size = private_size; 4654 4655 *private_size_or_offset = -(gint) node->data->instance.private_size; 4656 4657 G_WRITE_UNLOCK (&type_rw_lock); 4658 } 4659 4660 gpointer 4661 g_type_instance_get_private (GTypeInstance *instance, 4662 GType private_type) 4663 { 4664 TypeNode *node; 4665 4666 g_return_val_if_fail (instance != NULL && instance->g_class != NULL, NULL); 4667 4668 node = lookup_type_node_I (private_type); 4669 if (G_UNLIKELY (!node || !node->is_instantiatable)) 4670 { 4671 g_warning ("instance of invalid non-instantiatable type '%s'", 4672 type_descriptive_name_I (instance->g_class->g_type)); 4673 return NULL; 4674 } 4675 4676 return ((gchar *) instance) - node->data->instance.private_size; 4677 } 4678 4679 /** 4680 * g_type_class_get_instance_private_offset: (skip) 4681 * @g_class: a #GTypeClass 4682 * 4683 * Gets the offset of the private data for instances of @g_class. 4684 * 4685 * This is how many bytes you should add to the instance pointer of a 4686 * class in order to get the private data for the type represented by 4687 * @g_class. 4688 * 4689 * You can only call this function after you have registered a private 4690 * data area for @g_class using g_type_class_add_private(). 4691 * 4692 * Returns: the offset, in bytes 4693 * 4694 * Since: 2.38 4695 **/ 4696 gint 4697 g_type_class_get_instance_private_offset (gpointer g_class) 4698 { 4699 GType instance_type; 4700 guint16 parent_size; 4701 TypeNode *node; 4702 4703 g_assert (g_class != NULL); 4704 4705 instance_type = ((GTypeClass *) g_class)->g_type; 4706 node = lookup_type_node_I (instance_type); 4707 4708 g_assert (node != NULL); 4709 g_assert (node->is_instantiatable); 4710 4711 if (NODE_PARENT_TYPE (node)) 4712 { 4713 TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); 4714 4715 parent_size = pnode->data->instance.private_size; 4716 } 4717 else 4718 parent_size = 0; 4719 4720 if (node->data->instance.private_size == parent_size) 4721 g_error ("g_type_class_get_instance_private_offset() called on class %s but it has no private data", 4722 g_type_name (instance_type)); 4723 4724 return -(gint) node->data->instance.private_size; 4725 } 4726 4727 /** 4728 * g_type_add_class_private: 4729 * @class_type: GType of an classed type 4730 * @private_size: size of private structure 4731 * 4732 * Registers a private class structure for a classed type; 4733 * when the class is allocated, the private structures for 4734 * the class and all of its parent types are allocated 4735 * sequentially in the same memory block as the public 4736 * structures, and are zero-filled. 4737 * 4738 * This function should be called in the 4739 * type's get_type() function after the type is registered. 4740 * The private structure can be retrieved using the 4741 * G_TYPE_CLASS_GET_PRIVATE() macro. 4742 * 4743 * Since: 2.24 4744 */ 4745 void 4746 g_type_add_class_private (GType class_type, 4747 gsize private_size) 4748 { 4749 TypeNode *node = lookup_type_node_I (class_type); 4750 gsize offset; 4751 4752 g_return_if_fail (private_size > 0); 4753 4754 if (!node || !node->is_classed || !node->data) 4755 { 4756 g_warning ("cannot add class private field to invalid type '%s'", 4757 type_descriptive_name_I (class_type)); 4758 return; 4759 } 4760 4761 if (NODE_PARENT_TYPE (node)) 4762 { 4763 TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); 4764 if (node->data->class.class_private_size != pnode->data->class.class_private_size) 4765 { 4766 g_warning ("g_type_add_class_private() called multiple times for the same type"); 4767 return; 4768 } 4769 } 4770 4771 G_WRITE_LOCK (&type_rw_lock); 4772 4773 offset = ALIGN_STRUCT (node->data->class.class_private_size); 4774 node->data->class.class_private_size = offset + private_size; 4775 4776 G_WRITE_UNLOCK (&type_rw_lock); 4777 } 4778 4779 gpointer 4780 g_type_class_get_private (GTypeClass *klass, 4781 GType private_type) 4782 { 4783 TypeNode *class_node; 4784 TypeNode *private_node; 4785 TypeNode *parent_node; 4786 gsize offset; 4787 4788 g_return_val_if_fail (klass != NULL, NULL); 4789 4790 class_node = lookup_type_node_I (klass->g_type); 4791 if (G_UNLIKELY (!class_node || !class_node->is_classed)) 4792 { 4793 g_warning ("class of invalid type '%s'", 4794 type_descriptive_name_I (klass->g_type)); 4795 return NULL; 4796 } 4797 4798 private_node = lookup_type_node_I (private_type); 4799 if (G_UNLIKELY (!private_node || !NODE_IS_ANCESTOR (private_node, class_node))) 4800 { 4801 g_warning ("attempt to retrieve private data for invalid type '%s'", 4802 type_descriptive_name_I (private_type)); 4803 return NULL; 4804 } 4805 4806 offset = ALIGN_STRUCT (class_node->data->class.class_size); 4807 4808 if (NODE_PARENT_TYPE (private_node)) 4809 { 4810 parent_node = lookup_type_node_I (NODE_PARENT_TYPE (private_node)); 4811 g_assert (parent_node->data && NODE_REFCOUNT (parent_node) > 0); 4812 4813 if (G_UNLIKELY (private_node->data->class.class_private_size == parent_node->data->class.class_private_size)) 4814 { 4815 g_warning ("g_type_instance_get_class_private() requires a prior call to g_type_add_class_private()"); 4816 return NULL; 4817 } 4818 4819 offset += ALIGN_STRUCT (parent_node->data->class.class_private_size); 4820 } 4821 4822 return G_STRUCT_MEMBER_P (klass, offset); 4823 } 4824 4825 /** 4826 * g_type_ensure: 4827 * @type: a #GType 4828 * 4829 * Ensures that the indicated @type has been registered with the 4830 * type system, and its _class_init() method has been run. 4831 * 4832 * In theory, simply calling the type's _get_type() method (or using 4833 * the corresponding macro) is supposed take care of this. However, 4834 * _get_type() methods are often marked %G_GNUC_CONST for performance 4835 * reasons, even though this is technically incorrect (since 4836 * %G_GNUC_CONST requires that the function not have side effects, 4837 * which _get_type() methods do on the first call). As a result, if 4838 * you write a bare call to a _get_type() macro, it may get optimized 4839 * out by the compiler. Using g_type_ensure() guarantees that the 4840 * type's _get_type() method is called. 4841 * 4842 * Since: 2.34 4843 */ 4844 void 4845 g_type_ensure (GType type) 4846 { 4847 /* In theory, @type has already been resolved and so there's nothing 4848 * to do here. But this protects us in the case where the function 4849 * gets inlined (as it might in gobject_init_ctor() above). 4850 */ 4851 if (G_UNLIKELY (type == (GType)-1)) 4852 g_error ("can't happen"); 4853 }