comparison libpurple/protocols/jabber/caps.c @ 25786:5ad14a53e266

Partial disapproval of b8fdbd255c614e7305f835b843a3414675a86a19 Don't refcount the Client Info struct. It's always owned by the capstable and will be freed via jabber_caps_uninit().
author Paul Aurich <paul@darkrain42.org>
date Fri, 19 Dec 2008 04:28:38 +0000
parents 3bec4f4db198
children c4fd9222dda1
comparison
equal deleted inserted replaced
25785:3bec4f4db198 25786:5ad14a53e266
114 g_free(key->ver); 114 g_free(key->ver);
115 g_free(key->hash); 115 g_free(key->hash);
116 g_free(key); 116 g_free(key);
117 } 117 }
118 118
119 JabberCapsClientInfo * 119 static void
120 jabber_caps_client_info_ref(JabberCapsClientInfo *info) 120 jabber_caps_client_info_destroy(JabberCapsClientInfo *info)
121 {
122 g_return_val_if_fail(info != NULL, NULL);
123 ++info->ref;
124 return info;
125 }
126
127 void
128 jabber_caps_client_info_unref(JabberCapsClientInfo *info)
129 { 121 {
130 if (info == NULL) 122 if (info == NULL)
131 return;
132
133 g_return_if_fail(info->ref != 0);
134
135 if (--info->ref != 0)
136 return; 123 return;
137 124
138 while(info->identities) { 125 while(info->identities) {
139 JabberIdentity *id = info->identities->data; 126 JabberIdentity *id = info->identities->data;
140 g_free(id->category); 127 g_free(id->category);
267 if(!strcmp(client->name, "client")) { 254 if(!strcmp(client->name, "client")) {
268 JabberCapsKey *key = g_new0(JabberCapsKey, 1); 255 JabberCapsKey *key = g_new0(JabberCapsKey, 1);
269 JabberCapsClientInfo *value = g_new0(JabberCapsClientInfo, 1); 256 JabberCapsClientInfo *value = g_new0(JabberCapsClientInfo, 1);
270 xmlnode *child; 257 xmlnode *child;
271 JabberCapsNodeExts *exts = NULL; 258 JabberCapsNodeExts *exts = NULL;
272 jabber_caps_client_info_ref(value);
273 key->node = g_strdup(xmlnode_get_attrib(client,"node")); 259 key->node = g_strdup(xmlnode_get_attrib(client,"node"));
274 key->ver = g_strdup(xmlnode_get_attrib(client,"ver")); 260 key->ver = g_strdup(xmlnode_get_attrib(client,"ver"));
275 key->hash = g_strdup(xmlnode_get_attrib(client,"hash")); 261 key->hash = g_strdup(xmlnode_get_attrib(client,"hash"));
276 262
277 /* v1.3 capabilities */ 263 /* v1.3 capabilities */
349 } 335 }
350 336
351 void jabber_caps_init(void) 337 void jabber_caps_init(void)
352 { 338 {
353 nodetable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)jabber_caps_node_exts_unref); 339 nodetable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)jabber_caps_node_exts_unref);
354 capstable = g_hash_table_new_full(jabber_caps_hash, jabber_caps_compare, jabber_caps_destroy_key, (GDestroyNotify)jabber_caps_client_info_unref); 340 capstable = g_hash_table_new_full(jabber_caps_hash, jabber_caps_compare, jabber_caps_destroy_key, (GDestroyNotify)jabber_caps_client_info_destroy);
355 jabber_caps_load(); 341 jabber_caps_load();
356 } 342 }
357 343
358 void jabber_caps_uninit(void) 344 void jabber_caps_uninit(void)
359 { 345 {
408 g_free(data->who); 394 g_free(data->who);
409 g_free(data->node); 395 g_free(data->node);
410 g_free(data->ver); 396 g_free(data->ver);
411 g_free(data->hash); 397 g_free(data->hash);
412 398
413 if (data->info) 399 /* If we have info here, it's already in the capstable, so don't free it */
414 jabber_caps_client_info_unref(data->info);
415 if (data->exts) 400 if (data->exts)
416 free_string_glist(data->exts); 401 free_string_glist(data->exts);
417 if (data->node_exts) 402 if (data->node_exts)
418 jabber_caps_node_exts_unref(data->node_exts); 403 jabber_caps_node_exts_unref(data->node_exts);
419 g_free(data); 404 g_free(data);
463 if (!hash || strcmp(hash, userdata->ver)) { 448 if (!hash || strcmp(hash, userdata->ver)) {
464 purple_debug_warning("jabber", "Could not validate caps info from %s\n", 449 purple_debug_warning("jabber", "Could not validate caps info from %s\n",
465 xmlnode_get_attrib(packet, "from")); 450 xmlnode_get_attrib(packet, "from"));
466 451
467 userdata->cb(NULL, NULL, userdata->cb_data); 452 userdata->cb(NULL, NULL, userdata->cb_data);
468 jabber_caps_client_info_unref(info); 453 jabber_caps_client_info_destroy(info);
469 cbplususerdata_unref(userdata); 454 cbplususerdata_unref(userdata);
470 g_free(hash); 455 g_free(hash);
471 return; 456 return;
472 } 457 }
473 458
479 * ours (along with our ref) */ 464 * ours (along with our ref) */
480 info->exts = userdata->node_exts; 465 info->exts = userdata->node_exts;
481 userdata->node_exts = NULL; 466 userdata->node_exts = NULL;
482 } 467 }
483 468
484 userdata->info = info;
485
486 key.node = userdata->node; 469 key.node = userdata->node;
487 key.ver = userdata->ver; 470 key.ver = userdata->ver;
488 key.hash = userdata->hash; 471 key.hash = userdata->hash;
489 472
490 /* Use the copy of this data already in the table if it exists or insert 473 /* Use the copy of this data already in the table if it exists or insert
491 * a new one if we need to */ 474 * a new one if we need to */
492 if ((value = g_hash_table_lookup(capstable, &key))) { 475 if ((value = g_hash_table_lookup(capstable, &key))) {
493 jabber_caps_client_info_unref(info); 476 jabber_caps_client_info_destroy(info);
494 jabber_caps_client_info_ref(value);
495 info = value; 477 info = value;
496 } else { 478 } else {
497 JabberCapsKey *n_key = g_new(JabberCapsKey, 1); 479 JabberCapsKey *n_key = g_new(JabberCapsKey, 1);
498 n_key->node = userdata->node; 480 n_key->node = userdata->node;
499 n_key->ver = userdata->ver; 481 n_key->ver = userdata->ver;
500 n_key->hash = userdata->hash; 482 n_key->hash = userdata->hash;
501 userdata->node = userdata->ver = userdata->hash = NULL; 483 userdata->node = userdata->ver = userdata->hash = NULL;
502 484
503 /* The capstable gets a reference */ 485 /* The capstable gets a reference */
504 g_hash_table_insert(capstable, n_key, jabber_caps_client_info_ref(info)); 486 g_hash_table_insert(capstable, n_key, info);
505 schedule_caps_save(); 487 schedule_caps_save();
506 } 488 }
489
490 userdata->info = info;
507 491
508 if (userdata->extOutstanding == 0) 492 if (userdata->extOutstanding == 0)
509 jabber_caps_get_info_complete(userdata); 493 jabber_caps_get_info_complete(userdata);
510 494
511 cbplususerdata_unref(userdata); 495 cbplususerdata_unref(userdata);
577 key.hash = (char *)hash; 561 key.hash = (char *)hash;
578 562
579 info = g_hash_table_lookup(capstable, &key); 563 info = g_hash_table_lookup(capstable, &key);
580 if (info && hash) { 564 if (info && hash) {
581 /* v1.5 - We already have all the information we care about */ 565 /* v1.5 - We already have all the information we care about */
582 cb(jabber_caps_client_info_ref(info), NULL, user_data); 566 cb(info, NULL, user_data);
583 return; 567 return;
584 } 568 }
585 569
586 userdata = g_new0(jabber_caps_cbplususerdata, 1); 570 userdata = g_new0(jabber_caps_cbplususerdata, 1);
587 /* This ref is given to fetching the basic node#ver info if we need it 571 /* This ref is given to fetching the basic node#ver info if we need it
593 userdata->node = g_strdup(node); 577 userdata->node = g_strdup(node);
594 userdata->ver = g_strdup(ver); 578 userdata->ver = g_strdup(ver);
595 userdata->hash = g_strdup(hash); 579 userdata->hash = g_strdup(hash);
596 580
597 if (info) { 581 if (info) {
598 userdata->info = jabber_caps_client_info_ref(info); 582 userdata->info = info;
599 } else { 583 } else {
600 /* If we don't have the basic information about the client, we need 584 /* If we don't have the basic information about the client, we need
601 * to fetch it. */ 585 * to fetch it. */
602 JabberIq *iq; 586 JabberIq *iq;
603 xmlnode *query; 587 xmlnode *query;
733 717
734 if (!query || strcmp(query->xmlns, "http://jabber.org/protocol/disco#info")) 718 if (!query || strcmp(query->xmlns, "http://jabber.org/protocol/disco#info"))
735 return 0; 719 return 0;
736 720
737 info = g_new0(JabberCapsClientInfo, 1); 721 info = g_new0(JabberCapsClientInfo, 1);
738 jabber_caps_client_info_ref(info);
739 722
740 for(child = query->child; child; child = child->next) { 723 for(child = query->child; child; child = child->next) {
741 if (!strcmp(child->name,"identity")) { 724 if (!strcmp(child->name,"identity")) {
742 /* parse identity */ 725 /* parse identity */
743 const char *category = xmlnode_get_attrib(child, "category"); 726 const char *category = xmlnode_get_attrib(child, "category");