From 0331da97735499948ed96f85dfd9381212d25d6e Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Wed, 7 Dec 2011 10:10:33 +0100 Subject: [PATCH] flow engine: introduce FlowRequeueMoveToSpare As part of a clean up of how FlowRequeue is used, introduce FlowRequeueMoveToSpare for moving a flow from a locked queue to the spare queue. --- src/flow-queue.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ src/flow-queue.h | 1 + src/flow.c | 6 ++++-- 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/flow-queue.c b/src/flow-queue.c index 9a7a85bb10..7c0e63f697 100644 --- a/src/flow-queue.c +++ b/src/flow-queue.c @@ -26,6 +26,7 @@ #include "suricata-common.h" #include "threads.h" #include "debug.h" +#include "flow-private.h" #include "flow-queue.h" #include "flow-util.h" #include "util-error.h" @@ -212,3 +213,56 @@ void FlowRequeueMoveToBot(Flow *f, FlowQueue *q) SCMutexUnlock(&q->mutex_q); } +/** + * \brief Transfer a flow from a queue to the spare queue + * + * \param f the flow to be transfered + * \param q the source queue, where the flow will be removed. This queue is locked. + * + * \note spare queue needs locking + */ +void FlowRequeueMoveToSpare(Flow *f, FlowQueue *q) +{ +#ifdef DEBUG + BUG_ON(q == NULL || f == NULL); +#endif /* DEBUG */ + + /* remove from old queue */ + if (q->top == f) + q->top = f->lnext; /* remove from queue top */ + if (q->bot == f) + q->bot = f->lprev; /* remove from queue bot */ + if (f->lprev != NULL) + f->lprev->lnext = f->lnext; /* remove from flow prev */ + if (f->lnext != NULL) + f->lnext->lprev = f->lprev; /* remove from flow next */ +#ifdef DEBUG + BUG_ON(q->len == 0); +#endif + if (q->len > 0) + q->len--; /* adjust len */ + + f->lnext = NULL; + f->lprev = NULL; + + /* now put it in spare */ + SCMutexLock(&flow_spare_q.mutex_q); + + /* add to new queue (append) */ + f->lprev = flow_spare_q.bot; + if (f->lprev != NULL) + f->lprev->lnext = f; + f->lnext = NULL; + flow_spare_q.bot = f; + if (flow_spare_q.top == NULL) + flow_spare_q.top = f; + + flow_spare_q.len++; +#ifdef DBG_PERF + if (flow_spare_q.len > flow_spare_q.dbg_maxlen) + flow_spare_q.dbg_maxlen = flow_spare_q.len; +#endif /* DBG_PERF */ + + SCMutexUnlock(&flow_spare_q.mutex_q); +} + diff --git a/src/flow-queue.h b/src/flow-queue.h index 76f0b3bac7..3dc2e77d7c 100644 --- a/src/flow-queue.h +++ b/src/flow-queue.h @@ -49,6 +49,7 @@ void FlowEnqueue (FlowQueue *, Flow *); Flow *FlowDequeue (FlowQueue *); void FlowRequeue(Flow *, FlowQueue *, FlowQueue *, uint8_t); void FlowRequeueMoveToBot(Flow *, FlowQueue *); +void FlowRequeueMoveToSpare(Flow *, FlowQueue *); #endif /* __FLOW_QUEUE_H__ */ diff --git a/src/flow.c b/src/flow.c index 83c87bebf4..6d65a294b8 100644 --- a/src/flow.c +++ b/src/flow.c @@ -351,8 +351,10 @@ static int FlowPrune(FlowQueue *q, struct timeval *ts, int try_cnt) cnt++; FlowClearMemory (f, f->protomap); Flow *next_flow = f->lnext; + /* move to spare list */ - FlowRequeue(f, q, &flow_spare_q, 0); + FlowRequeueMoveToSpare(f, q); + SCMutexUnlock(&f->m); f = next_flow; @@ -507,7 +509,7 @@ int FlowKill (FlowQueue *q) FlowClearMemory (f, f->protomap); /* move to spare list */ - FlowRequeue(f, q, &flow_spare_q, 0); + FlowRequeueMoveToSpare(f, q); SCMutexUnlock(&f->m);