X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilcclient%2Fclient_entry.c;h=4664dbaa75f770446b457b8b7d830b67cab2d524;hp=bdcdd1cabe47843af73bb0195e3ba335b477b5b1;hb=e9374395ec9747bddd3ea0bfd3e5a17717e97b31;hpb=90e14dc985628e0b0f86e604d511039d302dc956 diff --git a/lib/silcclient/client_entry.c b/lib/silcclient/client_entry.c index bdcdd1ca..4664dbaa 100644 --- a/lib/silcclient/client_entry.c +++ b/lib/silcclient/client_entry.c @@ -1010,16 +1010,15 @@ SilcBool silc_client_del_client(SilcClient client, SilcClientConnection conn, if (!client_entry) return FALSE; - if (silc_atomic_sub_int32(&client_entry->internal.deleted, 1) != 0) - { - SILC_LOG_DEBUG(("** WARNING ** Deleting a client twice %p", client_entry)); -// asm("int3"); - return FALSE; + SILC_LOG_DEBUG(("Marking client entry %p deleted")); + + if (silc_atomic_sub_int32(&client_entry->internal.deleted, 1) != 0) { + SILC_LOG_DEBUG(("Client entry %p already marked deleted")); + return FALSE; } silc_client_unref_client(client, conn, client_entry); return TRUE; - } /* Internal routine used to find client by ID and if not found this creates @@ -1075,31 +1074,32 @@ SilcClientEntry silc_client_ref_client(SilcClient client, void silc_client_unref_client(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry) { - if (client_entry) { - SilcBool ret; + SilcBool ret; - SILC_LOG_DEBUG(("Client %p refcnt %d->%d", client_entry, - silc_atomic_get_int32(&client_entry->internal.refcnt), - silc_atomic_get_int32(&client_entry->internal.refcnt) - 1)); + if (!client_entry) + return; - if (silc_atomic_sub_int32(&client_entry->internal.refcnt, 1) > 0) - return; - - SILC_LOG_DEBUG(("Deleting client %p (%d)", client_entry, - silc_atomic_get_int32(&client_entry->internal.deleted))); + SILC_LOG_DEBUG(("Client %p refcnt %d->%d", client_entry, + silc_atomic_get_int32(&client_entry->internal.refcnt), + silc_atomic_get_int32(&client_entry->internal.refcnt) - 1)); - silc_mutex_lock(conn->internal->lock); - ret = silc_idcache_del_by_context(conn->internal->client_cache, - client_entry, NULL); - silc_mutex_unlock(conn->internal->lock); + if (silc_atomic_sub_int32(&client_entry->internal.refcnt, 1) > 0) + return; - if (ret) { - /* Remove from channels */ - silc_client_remove_from_channels(client, conn, client_entry); + SILC_LOG_DEBUG(("Deleting client %p (%d)", client_entry, + silc_atomic_get_int32(&client_entry->internal.deleted))); - /* Free the client entry data */ - silc_client_del_client_entry(client, conn, client_entry); - } + silc_mutex_lock(conn->internal->lock); + ret = silc_idcache_del_by_context(conn->internal->client_cache, + client_entry, NULL); + silc_mutex_unlock(conn->internal->lock); + + if (ret) { + /* Remove from channels */ + silc_client_remove_from_channels(client, conn, client_entry); + + /* Free the client entry data */ + silc_client_del_client_entry(client, conn, client_entry); } } @@ -1709,10 +1709,10 @@ SilcBool silc_client_del_channel(SilcClient client, SilcClientConnection conn, if (!channel) return FALSE; - if (silc_atomic_sub_int32(&channel->internal.deleted, 1) > 0) - { - SILC_LOG_DEBUG(("** WARNING ** Deleting a channel twice %p", channel)); -// asm("int3"); + SILC_LOG_DEBUG(("Marking channel entry %p deleted")); + + if (silc_atomic_sub_int32(&channel->internal.deleted, 1) != 0) { + SILC_LOG_DEBUG(("Channel entry %p already marked deleted")); return FALSE; } @@ -1781,70 +1781,71 @@ SilcChannelEntry silc_client_ref_channel(SilcClient client, void silc_client_unref_channel(SilcClient client, SilcClientConnection conn, SilcChannelEntry channel_entry) { - if (channel_entry) { - SilcIDCacheEntry id_cache; - SilcBool ret = TRUE; - SilcCipher key; - SilcHmac hmac; - char *namec; - - SILC_LOG_DEBUG(("Channel %p refcnt %d->%d", channel_entry, - silc_atomic_get_int32(&channel_entry->internal.refcnt), - silc_atomic_get_int32(&channel_entry->internal.refcnt) - - 1)); + SilcIDCacheEntry id_cache; + SilcBool ret = TRUE; + SilcCipher key; + SilcHmac hmac; + char *namec; - if (silc_atomic_sub_int32(&channel_entry->internal.refcnt, 1) > 0) - return; + if (!channel_entry) + return; - SILC_LOG_DEBUG(("Deleting channel %p", channel_entry)); + SILC_LOG_DEBUG(("Channel %p refcnt %d->%d", channel_entry, + silc_atomic_get_int32(&channel_entry->internal.refcnt), + silc_atomic_get_int32(&channel_entry->internal.refcnt) + - 1)); - silc_mutex_lock(conn->internal->lock); - if (silc_idcache_find_by_context(conn->internal->channel_cache, channel_entry, + if (silc_atomic_sub_int32(&channel_entry->internal.refcnt, 1) > 0) + return; + + SILC_LOG_DEBUG(("Deleting channel %p", channel_entry)); + + silc_mutex_lock(conn->internal->lock); + if (silc_idcache_find_by_context(conn->internal->channel_cache, channel_entry, &id_cache)) { - namec = id_cache->name; - ret = silc_idcache_del_by_context(conn->internal->channel_cache, + namec = id_cache->name; + ret = silc_idcache_del_by_context(conn->internal->channel_cache, channel_entry, NULL); - silc_free(namec); - } - silc_mutex_unlock(conn->internal->lock); + silc_free(namec); + } + silc_mutex_unlock(conn->internal->lock); - if (!ret) - return; + if (!ret) + return; - silc_client_empty_channel(client, conn, channel_entry); - silc_client_del_channel_private_keys(client, conn, channel_entry); - silc_hash_table_free(channel_entry->user_list); - silc_free(channel_entry->channel_name); - silc_free(channel_entry->topic); - if (channel_entry->founder_key) - silc_pkcs_public_key_free(channel_entry->founder_key); - if (channel_entry->internal.send_key) - silc_cipher_free(channel_entry->internal.send_key); - if (channel_entry->internal.receive_key) - silc_cipher_free(channel_entry->internal.receive_key); - if (channel_entry->internal.hmac) - silc_hmac_free(channel_entry->internal.hmac); - if (channel_entry->internal.old_channel_keys) { - silc_dlist_start(channel_entry->internal.old_channel_keys); - while ((key = silc_dlist_get(channel_entry->internal.old_channel_keys))) - silc_cipher_free(key); - silc_dlist_uninit(channel_entry->internal.old_channel_keys); - } - if (channel_entry->internal.old_hmacs) { - silc_dlist_start(channel_entry->internal.old_hmacs); - while ((hmac = silc_dlist_get(channel_entry->internal.old_hmacs))) - silc_hmac_free(hmac); - silc_dlist_uninit(channel_entry->internal.old_hmacs); - } - if (channel_entry->channel_pubkeys) - silc_argument_list_free(channel_entry->channel_pubkeys, + silc_client_empty_channel(client, conn, channel_entry); + silc_client_del_channel_private_keys(client, conn, channel_entry); + silc_hash_table_free(channel_entry->user_list); + silc_free(channel_entry->channel_name); + silc_free(channel_entry->topic); + if (channel_entry->founder_key) + silc_pkcs_public_key_free(channel_entry->founder_key); + if (channel_entry->internal.send_key) + silc_cipher_free(channel_entry->internal.send_key); + if (channel_entry->internal.receive_key) + silc_cipher_free(channel_entry->internal.receive_key); + if (channel_entry->internal.hmac) + silc_hmac_free(channel_entry->internal.hmac); + if (channel_entry->internal.old_channel_keys) { + silc_dlist_start(channel_entry->internal.old_channel_keys); + while ((key = silc_dlist_get(channel_entry->internal.old_channel_keys))) + silc_cipher_free(key); + silc_dlist_uninit(channel_entry->internal.old_channel_keys); + } + if (channel_entry->internal.old_hmacs) { + silc_dlist_start(channel_entry->internal.old_hmacs); + while ((hmac = silc_dlist_get(channel_entry->internal.old_hmacs))) + silc_hmac_free(hmac); + silc_dlist_uninit(channel_entry->internal.old_hmacs); + } + if (channel_entry->channel_pubkeys) + silc_argument_list_free(channel_entry->channel_pubkeys, SILC_ARGUMENT_PUBLIC_KEY); - silc_atomic_uninit32(&channel_entry->internal.deleted); - silc_atomic_uninit32(&channel_entry->internal.refcnt); - silc_rwlock_free(channel_entry->internal.lock); - silc_schedule_task_del_by_context(conn->client->schedule, channel_entry); - silc_free(channel_entry); - } + silc_atomic_uninit32(&channel_entry->internal.deleted); + silc_atomic_uninit32(&channel_entry->internal.refcnt); + silc_rwlock_free(channel_entry->internal.lock); + silc_schedule_task_del_by_context(conn->client->schedule, channel_entry); + silc_free(channel_entry); } /* Free channel entry list */