]> 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)
committerVictor Julien <victor@inliniac.net>
Fri, 17 Apr 2020 11:21:37 +0000 (13:21 +0200)
src/util-thash.c
src/util-thash.h

index abe6131c7e004816afc655162eee27f3c6310529..b9caee68cfc5e52c41b54c3f3c1175c2a2de9eb4 100644 (file)
@@ -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;
+}
index 8ebd210fed47f9216d19040d2d2352d27b993788..692a6ee683e62ce9aa2ef73e5b21def068ec027d 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__ */