mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-01-05 22:39:35 -05:00
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:
parent
fcac316d63
commit
2dbc83d5ae
6 changed files with 60 additions and 3 deletions
|
|
@ -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.
|
||||
|
|
|
|||
9
services/cache/rrset.c
vendored
9
services/cache/rrset.c
vendored
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. ***/
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Reference in a new issue