if (!client_entry)
return FALSE;
- if (silc_atomic_sub_int8(&client_entry->internal.refcnt, 1) > 0)
- return FALSE;
-
- SILC_LOG_DEBUG(("Deleting client %p", 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);
- 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"));
+
- /* Free the client entry data */
- silc_client_del_client_entry(client, conn, client_entry);
++ if (silc_atomic_sub_int32(&client_entry->internal.deleted, 1) != 0) {
++ SILC_LOG_DEBUG(("Client entry %p already marked deleted"));
++ return FALSE;
}
- return ret;
+ silc_client_unref_client(client, conn, client_entry);
+ return TRUE;
-
}
/* Internal routine used to find client by ID and if not found this creates
void silc_client_unref_client(SilcClient client, SilcClientConnection conn,
SilcClientEntry client_entry)
{
-- if (client_entry) {
- SILC_LOG_DEBUG(("Client %p refcnt %d->%d", client_entry,
- silc_atomic_get_int8(&client_entry->internal.refcnt),
- silc_atomic_get_int8(&client_entry->internal.refcnt) - 1));
- silc_client_del_client(client, conn, 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);
}
}
if (!channel)
return FALSE;
- if (silc_atomic_sub_int16(&channel->internal.refcnt, 1) > 0)
- return FALSE;
-
- SILC_LOG_DEBUG(("Deleting channel %p", channel));
- 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"));
+
- silc_mutex_lock(conn->internal->lock);
- if (silc_idcache_find_by_context(conn->internal->channel_cache, channel,
- &id_cache)) {
- namec = id_cache->name;
- ret = silc_idcache_del_by_context(conn->internal->channel_cache,
- channel, NULL);
- silc_free(namec);
- }
- silc_mutex_unlock(conn->internal->lock);
-
- if (!ret)
++ if (silc_atomic_sub_int32(&channel->internal.deleted, 1) != 0) {
++ SILC_LOG_DEBUG(("Channel entry %p already marked deleted"));
return FALSE;
-
- silc_client_empty_channel(client, conn, channel);
- silc_client_del_channel_private_keys(client, conn, channel);
- silc_hash_table_free(channel->user_list);
- silc_free(channel->channel_name);
- silc_free(channel->topic);
- if (channel->founder_key)
- silc_pkcs_public_key_free(channel->founder_key);
- if (channel->internal.send_key)
- silc_cipher_free(channel->internal.send_key);
- if (channel->internal.receive_key)
- silc_cipher_free(channel->internal.receive_key);
- if (channel->internal.hmac)
- silc_hmac_free(channel->internal.hmac);
- if (channel->internal.old_channel_keys) {
- silc_dlist_start(channel->internal.old_channel_keys);
- while ((key = silc_dlist_get(channel->internal.old_channel_keys)))
- silc_cipher_free(key);
- silc_dlist_uninit(channel->internal.old_channel_keys);
}
- if (channel->internal.old_hmacs) {
- silc_dlist_start(channel->internal.old_hmacs);
- while ((hmac = silc_dlist_get(channel->internal.old_hmacs)))
- silc_hmac_free(hmac);
- silc_dlist_uninit(channel->internal.old_hmacs);
- }
- if (channel->channel_pubkeys)
- silc_argument_list_free(channel->channel_pubkeys,
- SILC_ARGUMENT_PUBLIC_KEY);
- silc_atomic_uninit16(&channel->internal.refcnt);
- silc_rwlock_free(channel->internal.lock);
- silc_schedule_task_del_by_context(conn->client->schedule, channel);
- silc_free(channel);
- return ret;
+ silc_client_unref_channel(client, conn, channel);
+ return TRUE;
}
/* Replaces the channel ID of the `channel' to `new_id'. Returns FALSE
void silc_client_unref_channel(SilcClient client, SilcClientConnection conn,
SilcChannelEntry channel_entry)
{
-- if (channel_entry) {
- SILC_LOG_DEBUG(("Channel %p refcnt %d->%d", channel_entry,
- silc_atomic_get_int16(&channel_entry->internal.refcnt),
- silc_atomic_get_int16(&channel_entry->internal.refcnt)
- - 1));
- silc_client_del_channel(client, conn, channel_entry);
- SilcIDCacheEntry id_cache;
- SilcBool ret = TRUE;
- SilcCipher key;
- SilcHmac hmac;
- char *namec;
++ 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));
++ if (!channel_entry)
++ return;
+
- if (silc_atomic_sub_int32(&channel_entry->internal.refcnt, 1) > 0)
- return;
++ 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_LOG_DEBUG(("Deleting channel %p", channel_entry));
++ if (silc_atomic_sub_int32(&channel_entry->internal.refcnt, 1) > 0)
++ return;
+
- silc_mutex_lock(conn->internal->lock);
- if (silc_idcache_find_by_context(conn->internal->channel_cache, channel_entry,
++ 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 */