]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
thash: add 'remove' support
authorVictor Julien <victor@inliniac.net>
Mon, 13 Apr 2020 14:31:35 +0000 (16:31 +0200)
committerJeff Lucovsky <jeff@lucovsky.org>
Fri, 24 Apr 2020 14:06:26 +0000 (10:06 -0400)
(cherry picked from commit 51726e0a0f9c56c452cf9c4a566ba302a26cb1d4)

src/util-thash.c
src/util-thash.h

index 5b4f688c44052cc80c012723a89c259652fd737b..28022276d4880cbf1efbf948994cf636a464d6a2 100644 (file)
@@ -744,3 +744,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;
+}
index 0418663e32d370820e941ed9cccfa97f6680ac41..92b79e7bca1142ace02717f852fa1ae11fa14722 100644 (file)
@@ -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__ */