markdelfunc for lock order problem in lruhash reclaim().

git-svn-id: file:///svn/unbound/trunk@804 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-12-04 21:18:25 +00:00
parent fcac316d63
commit 2dbc83d5ae
6 changed files with 60 additions and 3 deletions

View file

@ -16,6 +16,8 @@
- hardening, if error reply with rcode=0 (noerror) send servfail.
- fixup same (*var) error in find_rrset in msgparse, was harmless.
- check return value of evtimer_add().
- fixup lockorder in lruhash_reclaim(), building up a list of locked
entries one at a time. Instead they are removed and unlocked.
3 December 2007: Wouter
- changed checkconf/ to smallapp/ to make room for more support tools.

View file

@ -47,6 +47,14 @@
#include "util/regional.h"
#include "util/alloc.h"
/** mark rrset to be deleted */
static void
rrset_markdel(void* key)
{
struct ub_packed_rrset_key* r = (struct ub_packed_rrset_key*)key;
r->id = 0;
}
struct rrset_cache* rrset_cache_create(struct config_file* cfg,
struct alloc_cache* alloc)
{
@ -57,6 +65,7 @@ struct rrset_cache* rrset_cache_create(struct config_file* cfg,
struct rrset_cache *r = (struct rrset_cache*)slabhash_create(slabs,
startarray, maxmem, ub_rrset_sizefunc, ub_rrset_compare,
ub_rrset_key_delete, rrset_data_delete, alloc);
slabhash_setmarkdel(&r->table, &rrset_markdel);
return r;
}

View file

@ -205,6 +205,10 @@ reclaim_space(struct lruhash* table, struct lruhash_entry** list)
*list = d;
lock_rw_wrlock(&d->lock);
table->space_used -= table->sizefunc(d->key, d->data);
if(table->markdelfunc)
/* TODO fptr_wlist it */
(*table->markdelfunc)(d->key);
lock_rw_unlock(&d->lock);
lock_quick_unlock(&bin->lock);
}
}
@ -341,7 +345,7 @@ lruhash_insert(struct lruhash* table, hashvalue_t hash,
while(reclaimlist) {
struct lruhash_entry* n = reclaimlist->overflow_next;
void* d = reclaimlist->data;
(*table->delkeyfunc)(reclaimlist->key, cb_arg, 1);
(*table->delkeyfunc)(reclaimlist->key, cb_arg, 0);
(*table->deldatafunc)(d, cb_arg);
reclaimlist = n;
}
@ -395,10 +399,14 @@ lruhash_remove(struct lruhash* table, hashvalue_t hash, void* key)
table->space_used -= (*table->sizefunc)(entry->key, entry->data);
lock_quick_unlock(&table->lock);
lock_rw_wrlock(&entry->lock);
if(table->markdelfunc)
/* TODO fptr wlist it */
(*table->markdelfunc)(entry->key);
lock_rw_unlock(&entry->lock);
lock_quick_unlock(&bin->lock);
/* finish removal */
d = entry->data;
(*table->delkeyfunc)(entry->key, table->cb_arg, 1);
(*table->delkeyfunc)(entry->key, table->cb_arg, 0);
(*table->deldatafunc)(d, table->cb_arg);
}
@ -414,7 +422,11 @@ bin_clear(struct lruhash* table, struct lruhash_bin* bin)
lock_rw_wrlock(&p->lock);
np = p->overflow_next;
d = p->data;
(*table->delkeyfunc)(p->key, table->cb_arg, 1);
if(table->markdelfunc)
/* TODO fptr wlist it */
(*table->markdelfunc)(p->key);
lock_rw_unlock(&p->lock);
(*table->delkeyfunc)(p->key, table->cb_arg, 0);
(*table->deldatafunc)(d, table->cb_arg);
p = np;
}
@ -491,3 +503,11 @@ lruhash_get_mem(struct lruhash* table)
s += lock_get_mem(&table->lock);
return s;
}
void
lruhash_setmarkdel(struct lruhash* table, lruhash_markdelfunc_t md)
{
lock_quick_lock(&table->lock);
table->markdelfunc = md;
lock_quick_unlock(&table->lock);
}

View file

@ -141,6 +141,10 @@ typedef void (*lruhash_delkeyfunc_t)(void*, void*, int);
/** old data is deleted. This function is called: func(data, userarg). */
typedef void (*lruhash_deldatafunc_t)(void*, void*);
/** mark a key as pending to be deleted (and not to be used by anyone).
* called: func(key) */
typedef void (*lruhash_markdelfunc_t)(void*);
/**
* Hash table that keeps LRU list of entries.
*/
@ -155,6 +159,8 @@ struct lruhash {
lruhash_delkeyfunc_t delkeyfunc;
/** how to delete data. */
lruhash_deldatafunc_t deldatafunc;
/** how to mark a key pending deletion */
lruhash_markdelfunc_t markdelfunc;
/** user argument for user functions */
void* cb_arg;
@ -294,6 +300,11 @@ struct lruhash_entry* lruhash_lookup(struct lruhash* table, hashvalue_t hash,
*/
void lru_touch(struct lruhash* table, struct lruhash_entry* entry);
/**
* Set the markdelfunction (or NULL)
*/
void lruhash_setmarkdel(struct lruhash* table, lruhash_markdelfunc_t md);
/************************* Internal functions ************************/
/*** these are only exposed for unit tests. ***/

View file

@ -202,3 +202,11 @@ void test_slabhash_deldata(void* data, void* ATTR_UNUSED(arg))
{
deldata((struct slabhash_testdata*)data);
}
void slabhash_setmarkdel(struct slabhash* sl, lruhash_markdelfunc_t md)
{
size_t i;
for(i=0; i<sl->size; i++) {
lruhash_setmarkdel(sl->array[i], md);
}
}

View file

@ -167,6 +167,13 @@ size_t slabhash_get_mem(struct slabhash* table);
*/
struct lruhash* slabhash_gettable(struct slabhash* table, hashvalue_t hash);
/**
* Set markdel function
* @param table: slabbed hash table.
* @param md: markdel function ptr.
*/
void slabhash_setmarkdel(struct slabhash* table, lruhash_markdelfunc_t md);
/* --- test representation --- */
/** test structure contains test key */
struct slabhash_testkey {