X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcclient%2Fclient_entry.c;fp=lib%2Fsilcclient%2Fclient_entry.c;h=a7ec24ee2701801ad02b235fe6c773a54bc37149;hb=3192ac4ddd09cd3fabe10a88cd5c885f217650a4;hp=4664dbaa75f770446b457b8b7d830b67cab2d524;hpb=711fe01f210030b40ce0aeceb1c18526632ba5b8;p=silc.git diff --git a/lib/silcclient/client_entry.c b/lib/silcclient/client_entry.c index 4664dbaa..a7ec24ee 100644 --- a/lib/silcclient/client_entry.c +++ b/lib/silcclient/client_entry.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2001 - 2007 Pekka Riikonen + Copyright (C) 2001 - 2008 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -815,6 +815,9 @@ SilcClientEntry silc_client_add_client(SilcClient client, NULL, NULL, NULL, TRUE); if (!client_entry->channels) { silc_free(client_entry->realname); + silc_atomic_uninit32(&client_entry->internal.deleted); + silc_atomic_uninit32(&client_entry->internal.refcnt); + silc_rwlock_free(client_entry->internal.lock); silc_free(client_entry); return NULL; } @@ -824,8 +827,11 @@ SilcClientEntry silc_client_add_client(SilcClient client, nick = silc_identifier_check(parsed, strlen(parsed), SILC_STRING_UTF8, 128, NULL); if (!nick) { - silc_free(client_entry->realname); silc_hash_table_free(client_entry->channels); + silc_free(client_entry->realname); + silc_atomic_uninit32(&client_entry->internal.deleted); + silc_atomic_uninit32(&client_entry->internal.refcnt); + silc_rwlock_free(client_entry->internal.lock); silc_free(client_entry); return NULL; } @@ -837,8 +843,11 @@ SilcClientEntry silc_client_add_client(SilcClient client, if (!silc_idcache_add(conn->internal->client_cache, nick, &client_entry->id, client_entry)) { silc_free(nick); - silc_free(client_entry->realname); silc_hash_table_free(client_entry->channels); + silc_free(client_entry->realname); + silc_atomic_uninit32(&client_entry->internal.deleted); + silc_atomic_uninit32(&client_entry->internal.refcnt); + silc_rwlock_free(client_entry->internal.lock); silc_free(client_entry); silc_mutex_unlock(conn->internal->lock); return NULL; @@ -1652,6 +1661,7 @@ SilcChannelEntry silc_client_add_channel(SilcClient client, if (!channel->channel_name) { silc_rwlock_free(channel->internal.lock); silc_atomic_uninit32(&channel->internal.refcnt); + silc_atomic_uninit32(&channel->internal.deleted); silc_free(channel); return NULL; } @@ -1661,6 +1671,7 @@ SilcChannelEntry silc_client_add_channel(SilcClient client, if (!channel->user_list) { silc_rwlock_free(channel->internal.lock); silc_atomic_uninit32(&channel->internal.refcnt); + silc_atomic_uninit32(&channel->internal.deleted); silc_free(channel->channel_name); silc_free(channel); return NULL; @@ -1672,6 +1683,7 @@ SilcChannelEntry silc_client_add_channel(SilcClient client, if (!channel_namec) { silc_rwlock_free(channel->internal.lock); silc_atomic_uninit32(&channel->internal.refcnt); + silc_atomic_uninit32(&channel->internal.deleted); silc_free(channel->channel_name); silc_hash_table_free(channel->user_list); silc_free(channel); @@ -1685,6 +1697,7 @@ SilcChannelEntry silc_client_add_channel(SilcClient client, &channel->id, channel)) { silc_rwlock_free(channel->internal.lock); silc_atomic_uninit32(&channel->internal.refcnt); + silc_atomic_uninit32(&channel->internal.deleted); silc_free(channel_namec); silc_free(channel->channel_name); silc_hash_table_free(channel->user_list); @@ -2081,6 +2094,7 @@ SilcServerEntry silc_client_add_server(SilcClient client, silc_rwlock_alloc(&server_entry->internal.lock); silc_atomic_init32(&server_entry->internal.refcnt, 0); + silc_atomic_init32(&server_entry->internal.deleted, 1); server_entry->id = *server_id; if (server_name) server_entry->server_name = strdup(server_name); @@ -2094,6 +2108,9 @@ SilcServerEntry silc_client_add_server(SilcClient client, if (!server_namec) { silc_free(server_entry->server_name); silc_free(server_entry->server_info); + silc_atomic_uninit32(&server_entry->internal.deleted); + silc_atomic_uninit32(&server_entry->internal.refcnt); + silc_rwlock_free(server_entry->internal.lock); silc_free(server_entry); return NULL; } @@ -2107,6 +2124,9 @@ SilcServerEntry silc_client_add_server(SilcClient client, silc_free(server_namec); silc_free(server_entry->server_name); silc_free(server_entry->server_info); + silc_atomic_uninit32(&server_entry->internal.deleted); + silc_atomic_uninit32(&server_entry->internal.refcnt); + silc_rwlock_free(server_entry->internal.lock); silc_free(server_entry); silc_mutex_unlock(conn->internal->lock); return NULL; @@ -2125,37 +2145,14 @@ SilcServerEntry silc_client_add_server(SilcClient client, SilcBool silc_client_del_server(SilcClient client, SilcClientConnection conn, SilcServerEntry server) { - SilcIDCacheEntry id_cache; - SilcBool ret = TRUE; - char *namec; - if (!server) return FALSE; - if (silc_atomic_sub_int32(&server->internal.refcnt, 1) > 0) + if (silc_atomic_sub_int32(&server->internal.deleted, 1) != 0) return FALSE; - SILC_LOG_DEBUG(("Deleting server %p", server)); - - silc_mutex_lock(conn->internal->lock); - if (silc_idcache_find_by_context(conn->internal->server_cache, server, - &id_cache)) { - namec = id_cache->name; - ret = silc_idcache_del_by_context(conn->internal->server_cache, - server, NULL); - silc_free(namec); - } - silc_mutex_unlock(conn->internal->lock); - - silc_free(server->server_name); - silc_free(server->server_info); - if (server->public_key) - silc_pkcs_public_key_free(server->public_key); - silc_atomic_uninit32(&server->internal.refcnt); - silc_rwlock_free(server->internal.lock); - silc_free(server); - - return ret; + silc_client_unref_server(client, conn, server); + return TRUE; } /* Updates the `server_entry' with the new information sent as argument. */ @@ -2231,13 +2228,36 @@ SilcServerEntry silc_client_ref_server(SilcClient client, void silc_client_unref_server(SilcClient client, SilcClientConnection conn, SilcServerEntry server_entry) { - if (server_entry) { - SILC_LOG_DEBUG(("Server %p refcnt %d->%d", server_entry, - silc_atomic_get_int32(&server_entry->internal.refcnt), - silc_atomic_get_int32(&server_entry->internal.refcnt) - - 1)); - silc_client_del_server(client, conn, server_entry); + SilcBool ret; + SilcIDCacheEntry id_cache; + char *namec; + + if (!server_entry) + return; + + if (silc_atomic_sub_int32(&server_entry->internal.refcnt, 1) > 0) + return; + + SILC_LOG_DEBUG(("Deleting server %p", server_entry)); + + silc_mutex_lock(conn->internal->lock); + if (silc_idcache_find_by_context(conn->internal->server_cache, server_entry, + &id_cache)) { + namec = id_cache->name; + ret = silc_idcache_del_by_context(conn->internal->server_cache, + server_entry, NULL); + silc_free(namec); } + silc_mutex_unlock(conn->internal->lock); + + silc_free(server_entry->server_name); + silc_free(server_entry->server_info); + if (server_entry->public_key) + silc_pkcs_public_key_free(server_entry->public_key); + silc_atomic_uninit32(&server_entry->internal.deleted); + silc_atomic_uninit32(&server_entry->internal.refcnt); + silc_rwlock_free(server_entry->internal.lock); + silc_free(server_entry); } /* Free server entry list */