From ff97d7c15da0a8a7b8ea1a0d461f4f56ca2052d6 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Mon, 4 Oct 2021 09:24:51 +0200 Subject: [PATCH] threading: force break loop on flow inject Track availability of break loop callback to avoid overhead. --- src/threadvars.h | 1 + src/tm-threads.c | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/threadvars.h b/src/threadvars.h index 1089dd132d..8b604445ed 100644 --- a/src/threadvars.h +++ b/src/threadvars.h @@ -132,6 +132,7 @@ typedef struct ThreadVars_ { SCCtrlCondT *ctrl_cond; struct FlowQueue_ *flow_queue; + bool break_loop; } ThreadVars; diff --git a/src/tm-threads.c b/src/tm-threads.c index ed01e26a71..b87700d289 100644 --- a/src/tm-threads.c +++ b/src/tm-threads.c @@ -668,6 +668,9 @@ void TmSlotSetFuncAppend(ThreadVars *tv, TmModule *tm, const void *data) slot->SlotFunc = tm->Func; } else if (tm->PktAcqLoop) { slot->PktAcqLoop = tm->PktAcqLoop; + if (tm->PktAcqBreakLoop) { + tv->break_loop = true; + } } else if (tm->Management) { slot->Management = tm->Management; } @@ -2319,6 +2322,23 @@ uint16_t TmThreadsGetWorkerThreadMax() return thread_max; } +static inline void ThreadBreakLoop(ThreadVars *tv) +{ + if ((tv->tmm_flags & TM_FLAG_RECEIVE_TM) == 0) { + return; + } + /* find the correct slot */ + TmSlot *s = tv->tm_slots; + TmModule *tm = TmModuleGetById(s->tm_id); + if (tm->flags & TM_FLAG_RECEIVE_TM) { + /* if the method supports it, BreakLoop. Otherwise we rely on + * the capture method's recv timeout */ + if (tm->PktAcqLoop && tm->PktAcqBreakLoop) { + tm->PktAcqBreakLoop(tv, SC_ATOMIC_GET(s->slot_data)); + } + } +} + /** * \retval r 1 if packet was accepted, 0 otherwise * \note if packet was not accepted, it's still the responsibility @@ -2347,6 +2367,8 @@ int TmThreadsInjectPacketsById(Packet **packets, const int id) /* wake up listening thread(s) if necessary */ if (tv->inq != NULL) { SCCondSignal(&tv->inq->pq->cond_q); + } else if (tv->break_loop) { + ThreadBreakLoop(tv); } return 1; } @@ -2369,5 +2391,7 @@ void TmThreadsInjectFlowById(Flow *f, const int id) /* wake up listening thread(s) if necessary */ if (tv->inq != NULL) { SCCondSignal(&tv->inq->pq->cond_q); + } else if (tv->break_loop) { + ThreadBreakLoop(tv); } }