From: Victor Julien Date: Mon, 13 Apr 2020 14:31:35 +0000 (+0200) Subject: thash: add 'remove' support X-Git-Tag: suricata-6.0.0-beta1~495 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=51726e0a0f9c56c452cf9c4a566ba302a26cb1d4;p=thirdparty%2Fsuricata.git thash: add 'remove' support --- diff --git a/src/util-thash.c b/src/util-thash.c index abe6131c7e..b9caee68cf 100644 --- a/src/util-thash.c +++ b/src/util-thash.c @@ -737,3 +737,62 @@ static THashData *THashGetUsed(THashTableContext *ctx) return NULL; } + +/** + * \retval int -1 not found + * \retval int 0 found, but it was busy (ref cnt) + * \retval int 1 found and removed */ +int THashRemoveFromHash (THashTableContext *ctx, void *data) +{ + /* get the key to our bucket */ + uint32_t key = THashGetKey(&ctx->config, data); + /* get our hash bucket and lock it */ + THashHashRow *hb = &ctx->array[key]; + + HRLOCK_LOCK(hb); + if (hb->head == NULL) { + HRLOCK_UNLOCK(hb); + SCLogDebug("empty hash row"); + return -1; + } + + /* ok, we have data in the bucket. Let's find out if it is our data */ + THashData *h = hb->head; + do { + /* see if this is the data we are looking for */ + if (THashCompare(&ctx->config, h->data, data) == 0) { + h = h->next; + continue; + } + + SCMutexLock(&h->m); + if (SC_ATOMIC_GET(h->use_cnt) > 0) { + SCMutexUnlock(&h->m); + HRLOCK_UNLOCK(hb); + return 0; + } + + /* remove from the hash */ + if (h->prev != NULL) + h->prev->next = h->next; + if (h->next != NULL) + h->next->prev = h->prev; + if (hb->head == h) + hb->head = h->next; + if (hb->tail == h) + hb->tail = h->prev; + + h->next = NULL; + h->prev = NULL; + SCMutexUnlock(&h->m); + HRLOCK_UNLOCK(hb); + THashDataFree(ctx, h); + SCLogDebug("found and removed"); + return 1; + + } while (h != NULL); + + HRLOCK_UNLOCK(hb); + SCLogDebug("data not found"); + return -1; +} diff --git a/src/util-thash.h b/src/util-thash.h index 8ebd210fed..692a6ee683 100644 --- a/src/util-thash.h +++ b/src/util-thash.h @@ -211,5 +211,6 @@ THashData *THashLookupFromHash (THashTableContext *ctx, void *data); THashDataQueue *THashDataQueueNew(void); void THashCleanup(THashTableContext *ctx); int THashWalk(THashTableContext *, THashFormatFunc, THashOutputFunc, void *); +int THashRemoveFromHash (THashTableContext *ctx, void *data); #endif /* __THASH_H__ */