Mercurial > pidgin.yaz
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"); |