X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilccore%2Fsilcidcache.c;h=3d6904e74421b00d962d69e55466f92c9240fa0a;hp=c4b658e80ed02f3827d06ad687de3c154e9577e1;hb=382d15d447b7a95390decfa783836ae4fe255b3d;hpb=7428855aff83c6dd40431bb88d3f1e5c973e7c06 diff --git a/lib/silccore/silcidcache.c b/lib/silccore/silcidcache.c index c4b658e8..3d6904e7 100644 --- a/lib/silccore/silcidcache.c +++ b/lib/silccore/silcidcache.c @@ -85,11 +85,11 @@ struct SilcIDCacheStruct { */ struct SilcIDCacheListStruct { - SilcIDCacheEntry cache[64]; + SilcIDCacheEntry cache[128]; SilcIDCacheEntry *cache_dyn; - uint32 cache_dyn_count; - uint32 cache_count; - uint32 pos; + SilcUInt32 cache_dyn_count; + SilcUInt32 cache_count; + SilcUInt32 pos; bool dyn; }; @@ -98,7 +98,7 @@ struct SilcIDCacheListStruct { The `id_type' defines the types of the ID's that will be saved to the cache. */ -SilcIDCache silc_idcache_alloc(uint32 count, SilcIdType id_type, +SilcIDCache silc_idcache_alloc(SilcUInt32 count, SilcIdType id_type, SilcIDCacheDestructor destructor) { SilcIDCache cache; @@ -106,20 +106,32 @@ SilcIDCache silc_idcache_alloc(uint32 count, SilcIdType id_type, SILC_LOG_DEBUG(("Allocating new cache")); cache = silc_calloc(1, sizeof(*cache)); - cache->id_table = silc_hash_table_alloc(count, silc_hash_id, - (void *)(uint32)id_type, - silc_hash_id_compare, - (void *)(uint32)id_type, - silc_idcache_destructor, NULL, - FALSE); + if (!cache) + return NULL; + cache->id_table = silc_hash_table_alloc(count, silc_hash_id, + (void *)(SilcUInt32)id_type, + silc_hash_id_compare, + (void *)(SilcUInt32)id_type, + silc_idcache_destructor, NULL, TRUE); cache->name_table = silc_hash_table_alloc(count, silc_hash_string, NULL, - silc_hash_string_compare, NULL, - NULL, NULL, FALSE); + silc_hash_string_compare, NULL, + NULL, NULL, TRUE); cache->context_table = silc_hash_table_alloc(count, silc_hash_ptr, NULL, - NULL, NULL, NULL, NULL, FALSE); + NULL, NULL, NULL, NULL, TRUE); cache->destructor = destructor; cache->type = id_type; + if (!cache->id_table || !cache->name_table || !cache->context_table) { + if (cache->id_table) + silc_hash_table_free(cache->id_table); + if (cache->name_table) + silc_hash_table_free(cache->name_table); + if (cache->context_table) + silc_hash_table_free(cache->context_table); + silc_free(cache); + return NULL; + } + return cache; } @@ -142,18 +154,19 @@ void silc_idcache_free(SilcIDCache cache) the entry never expires from the cache. */ bool silc_idcache_add(SilcIDCache cache, char *name, void *id, - void *context, int expire) + void *context, int expire, SilcIDCacheEntry *ret) { SilcIDCacheEntry c; - uint32 curtime = time(NULL); SILC_LOG_DEBUG(("Adding cache entry")); /* Allocate new cache entry */ c = silc_calloc(1, sizeof(*c)); + if (!c) + return FALSE; c->id = id; c->name = name; - c->expire = (expire ? (curtime + SILC_ID_CACHE_EXPIRE) : 0); + c->expire = expire; c->context = context; /* Add the new entry to the hash tables */ @@ -165,13 +178,8 @@ bool silc_idcache_add(SilcIDCache cache, char *name, void *id, if (context) silc_hash_table_add(cache->context_table, context, c); - /* See whether we have time to rehash the tables */ - if ((silc_hash_table_count(cache->id_table) / 2) > - silc_hash_table_size(cache->id_table)) { - silc_hash_table_rehash(cache->id_table, 0); - silc_hash_table_rehash(cache->name_table, 0); - silc_hash_table_rehash(cache->context_table, 0); - } + if (ret) + *ret = c; return TRUE; } @@ -181,7 +189,11 @@ bool silc_idcache_add(SilcIDCache cache, char *name, void *id, static void silc_idcache_destructor(void *key, void *context, void *user_context) { - silc_free(context); + SilcIDCacheEntry c = context; + if (c) { + memset(c, 'F', sizeof(*c)); + silc_free(c); + } } /* Delete cache entry from cache. */ @@ -199,7 +211,7 @@ bool silc_idcache_del(SilcIDCache cache, SilcIDCacheEntry old) if (old->id) ret = silc_hash_table_del(cache->id_table, old->id); else - silc_free(old); + silc_idcache_destructor(NULL, old, NULL); return ret; } @@ -266,7 +278,7 @@ bool silc_idcache_del_by_context(SilcIDCache cache, void *context) if (c->id) ret = silc_hash_table_del_by_context(cache->id_table, c->id, c); else - silc_free(c); + silc_idcache_destructor(NULL, c, NULL); return ret; } @@ -294,26 +306,33 @@ static void silc_idcache_purge_foreach(void *key, void *context, void *user_context) { SilcIDCache cache = (SilcIDCache)user_context; - uint32 curtime = time(NULL); + SilcUInt32 curtime = time(NULL); SilcIDCacheEntry c = (SilcIDCacheEntry)context; + bool ret = FALSE; + + if (!context) + return; if (c->expire && c->expire < curtime) { /* Remove the entry from the hash tables */ if (c->name) - silc_hash_table_del_by_context(cache->name_table, c->name, c); + ret = silc_hash_table_del_by_context(cache->name_table, c->name, c); if (c->context) - silc_hash_table_del(cache->context_table, c->context); + ret = silc_hash_table_del(cache->context_table, c->context); if (c->id) - silc_hash_table_del_by_context_ext(cache->id_table, c->id, c, - NULL, NULL, NULL, NULL, - silc_idcache_destructor_dummy, NULL); - - /* Call the destructor */ - if (cache->destructor) - cache->destructor(cache, c); - - /* Free the entry, it has been deleted from the hash tables */ - silc_free(c); + ret = + silc_hash_table_del_by_context_ext(cache->id_table, c->id, c, + NULL, NULL, NULL, NULL, + silc_idcache_destructor_dummy, + NULL); + if (ret == TRUE) { + /* Call the destructor */ + if (cache->destructor) + cache->destructor(cache, c); + + /* Free the entry, it has been deleted from the hash tables */ + silc_idcache_destructor(NULL, c, NULL); + } } } @@ -347,13 +366,14 @@ bool silc_idcache_purge_by_context(SilcIDCache cache, void *context) silc_hash_table_del_by_context_ext(cache->id_table, c->id, c, NULL, NULL, NULL, NULL, silc_idcache_destructor_dummy, NULL); - - /* Call the destructor */ - if (cache->destructor) - cache->destructor(cache, c); + if (ret == TRUE) { + /* Call the destructor */ + if (cache->destructor) + cache->destructor(cache, c); - /* Free the entry, it has been deleted from the hash tables */ - silc_free(c); + /* Free the entry, it has been deleted from the hash tables */ + silc_idcache_destructor(NULL, c, NULL); + } return ret; } @@ -365,6 +385,8 @@ static void silc_idcache_get_all_foreach(void *key, void *context, void *user_context) { SilcIDCacheList list = (SilcIDCacheList)user_context; + if (!context) + return; silc_idcache_list_add(list, (SilcIDCacheEntry)context); } @@ -378,6 +400,8 @@ bool silc_idcache_get_all(SilcIDCache cache, SilcIDCacheList *ret) return TRUE; list = silc_idcache_list_alloc(); + if (!list) + return FALSE; silc_hash_table_foreach(cache->id_table, silc_idcache_get_all_foreach, list); if (silc_idcache_list_count(list) == 0) { @@ -398,6 +422,8 @@ bool silc_idcache_find_by_id(SilcIDCache cache, void *id, SilcIDCacheList list; list = silc_idcache_list_alloc(); + if (!list) + return FALSE; if (!ret) return TRUE; @@ -456,6 +482,8 @@ bool silc_idcache_find_by_name(SilcIDCache cache, char *name, SilcIDCacheList list; list = silc_idcache_list_alloc(); + if (!list) + return FALSE; if (!ret) return TRUE; @@ -491,6 +519,8 @@ static SilcIDCacheList silc_idcache_list_alloc() SilcIDCacheList list; list = silc_calloc(1, sizeof(*list)); + if (!list) + return FALSE; return list; } @@ -527,6 +557,8 @@ static void silc_idcache_list_add(SilcIDCacheList list, SilcIDCacheEntry cache) i = list->cache_dyn_count; list->cache_dyn = silc_realloc(list->cache_dyn, sizeof(*list->cache_dyn) * (i + 5)); + if (!list->cache_dyn) + return; /* NULL the reallocated area */ for (k = i; k < (i + 5); k++)