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