From 98232498b817536cfd1e11bccb23e2f7fdd5832b Mon Sep 17 00:00:00 2001 From: Florent Bruneau Date: Wed, 17 Sep 2008 23:30:54 +0200 Subject: [PATCH] Array contains a "lock" flag, allowing "per array" locking. Signed-off-by: Florent Bruneau --- common/array.h | 42 +++++++++++++++++++++++++++++--------- common/trie.c | 5 ----- postlicyd/main-postlicyd.c | 2 +- postlicyd/rbl.c | 9 ++------ postlicyd/strlist.c | 24 +++++++++++----------- 5 files changed, 47 insertions(+), 35 deletions(-) diff --git a/common/array.h b/common/array.h index dadce33..55883d2 100644 --- a/common/array.h +++ b/common/array.h @@ -43,8 +43,9 @@ #define PRIV_ARRAY(Type) \ struct { \ Type *data; \ - ssize_t len; \ - ssize_t size; \ + uint32_t len; \ + uint32_t size; \ + unsigned locked : 1; \ } #define PARRAY(Type) \ @@ -57,6 +58,9 @@ static inline void Type ## _ptr_array_delete(Type ## _ptr_array_t **array) \ { \ if (*array) { \ + if ((*array)->locked) { \ + array_unlock(**array); \ + } \ array_wipe(**array); \ p_delete(array); \ } \ @@ -73,6 +77,9 @@ static inline void Type ## _array_delete(Type ## _array_t **array) \ { \ if (*array) { \ + if ((*array)->locked) { \ + array_unlock(**array); \ + } \ array_wipe(**array); \ p_delete(array); \ } \ @@ -83,11 +90,18 @@ #define A(Type) Type ## _array_t #define PA(Type) Type ## _ptr_array_t -#define ARRAY_INIT { NULL, 0, 0 } +#define ARRAY_INIT { NULL, 0, 0, false } #define array_init(array) (array) = ARRAY_INIT + +#define array_can_edit(array) (!(array).locked) + +#define array_ensure_can_edit(array) \ + assert(array_can_edit(array) && "Trying to edit array while it is locked") + #define array_wipe(array) \ do { \ + array_ensure_can_edit(array); \ p_delete(&(array).data); \ (array).len = 0; \ (array).size = 0; \ @@ -99,7 +113,7 @@ } while (0) #define array_append(array, objs, len) \ do { \ - const ssize_t __len = (len); \ + const typeof((array).len) __len = (len); \ array_ensure_capacity_delta(array, __len); \ memcpy((array).data + (array).len, objs, \ __len * sizeof(*(array).data)); \ @@ -107,9 +121,10 @@ } while (0) #define array_ensure_capacity(array, goal) \ do { \ + array_ensure_can_edit(array); \ if ((array).size < (goal)) { \ - const ssize_t required_size = (goal); \ - ssize_t next_size = (array).size; \ + const typeof((array).size) required_size = (goal); \ + typeof((array).size) next_size = (array).size; \ do { \ next_size = p_alloc_nr(next_size); \ } while (next_size < required_size); \ @@ -120,21 +135,23 @@ array_ensure_capacity(array, (array).len + (delta)) #define array_ensure_exact_capacity(array, goal) \ if (array_size(array) < (goal)) { \ + array_ensure_can_edit(array); \ p_allocgrow(&(array).data, (goal), &(array).size); \ } #define array_adjust(array) \ do { \ + array_ensure_can_edit(array); \ p_shrink(&(array).data, (array).len, &(array).size); \ } while (0) #define array_elt(array, n) (array).data[(n)] #define array_ptr(array, n) (array).data + (n) #define foreach(var, array) \ - for (int __Ai = 0 ; __Ai < (array).len ; ++__Ai) { \ + for (uint32_t __Ai = 0 ; __Ai < (array).len ; ++__Ai) { \ var = array_ptr(array, __Ai); #define array_foreach(array, action) \ - for (int __Ai = 0 ; __Ai < (array).len ; ++__Ai) { \ + for (uint32_t __Ai = 0 ; __Ai < (array).len ; ++__Ai) { \ action(array_ptr(array, __Ai)); \ } #define array_deep_wipe(array, wipe) \ @@ -144,9 +161,14 @@ } while (0) #define array_lock(array) \ - (mlock((array).data, (array).len * sizeof(*(array).data)) == 0) + ((array).locked || \ + (mlock((array).data, (array).len * sizeof(*(array).data)) == 0 \ + && ((array).locked = true))) #define array_unlock(array) \ - (void)munlock((array).data, (array).len * sizeof(*(array).data)) + if ((array).locked) { \ + (void)munlock((array).data, (array).len * sizeof(*(array).data)); \ + (array).locked = false; \ + } ARRAY(char) ARRAY(int) diff --git a/common/trie.c b/common/trie.c index 7d75d69..5df379c 100644 --- a/common/trie.c +++ b/common/trie.c @@ -334,17 +334,12 @@ void trie_lock(trie_t *trie) } if (!array_lock(trie->entries)) { UNIXERR("mlock"); - return; } if (!array_lock(trie->c)) { UNIXERR("mlock"); - array_unlock(trie->entries); - return; } if (mlock(trie, sizeof(trie_t)) != 0) { UNIXERR("mlock"); - array_unlock(trie->entries); - array_unlock(trie->c); return; } trie->locked = true; diff --git a/postlicyd/main-postlicyd.c b/postlicyd/main-postlicyd.c index d6c5cc4..bc65920 100644 --- a/postlicyd/main-postlicyd.c +++ b/postlicyd/main-postlicyd.c @@ -192,7 +192,7 @@ static bool policy_process(server_t *pcy, const config_t *config) static int policy_run(server_t *pcy, void* vconfig) { - ssize_t search_offs = MAX(0, pcy->ibuf.len - 1); + ssize_t search_offs = MAX(0, (ssize_t)(pcy->ibuf.len - 1)); int nb = buffer_read(&pcy->ibuf, pcy->fd, -1); const char *eoq; query_t *query = pcy->data; diff --git a/postlicyd/rbl.c b/postlicyd/rbl.c index 1bae4d8..1341f02 100644 --- a/postlicyd/rbl.c +++ b/postlicyd/rbl.c @@ -62,7 +62,6 @@ enum { struct rbldb_t { A(uint32_t) ips; - bool locked; }; ARRAY(rbldb_t) @@ -156,8 +155,7 @@ rbldb_t *rbldb_create(const char *file, bool lock) /* Lookup may perform serveral I/O, so avoid swap. */ array_adjust(db->ips); - db->locked = lock && array_lock(db->ips); - if (lock && !db->locked) { + if (lock && !array_lock(db->ips)) { UNIXERR("mlock"); } @@ -175,9 +173,6 @@ rbldb_t *rbldb_create(const char *file, bool lock) static void rbldb_wipe(rbldb_t *db) { - if (db->locked) { - array_unlock(db->ips); - } array_wipe(db->ips); } @@ -357,7 +352,7 @@ static filter_result_t rbl_filter(const filter_t *filter, const query_t *query) query->client_address); return HTK_ERROR; } - for (int i = 0 ; i < data->rbls.len ; ++i) { + for (uint32_t i = 0 ; i < data->rbls.len ; ++i) { const rbldb_t *rbl = array_elt(data->rbls, i); int weight = array_elt(data->weights, i); if (rbldb_ipv4_lookup(rbl, ip)) { diff --git a/postlicyd/strlist.c b/postlicyd/strlist.c index 20e6a58..875ee23 100644 --- a/postlicyd/strlist.c +++ b/postlicyd/strlist.c @@ -319,18 +319,18 @@ static filter_result_t strlist_filter(const filter_t *filter, const query_t *que return HTK_ABORT; } #define LOOKUP(Flag, Field) \ - if (config->match_ ## Flag) { \ - const int len = m_strlen(query->Field); \ - strlist_copy(normal, query->Field, len, false); \ - strlist_copy(reverse, query->Field, len, true); \ - for (int i = 0 ; i < config->tries.len ; ++i) { \ - const int weight = array_elt(config->weights, i); \ - const trie_t *trie = array_elt(config->tries, i); \ - const bool rev = array_elt(config->reverses, i); \ - if (trie_lookup(trie, rev ? reverse : normal)) { \ - sum += weight; \ - } \ - } \ + if (config->match_ ## Flag) { \ + const int len = m_strlen(query->Field); \ + strlist_copy(normal, query->Field, len, false); \ + strlist_copy(reverse, query->Field, len, true); \ + for (uint32_t i = 0 ; i < config->tries.len ; ++i) { \ + const int weight = array_elt(config->weights, i); \ + const trie_t *trie = array_elt(config->tries, i); \ + const bool rev = array_elt(config->reverses, i); \ + if (trie_lookup(trie, rev ? reverse : normal)) { \ + sum += weight; \ + } \ + } \ } if (config->is_email) { LOOKUP(sender, sender); -- 2.20.1