/** * \brief Force reassembly for all the flows that have unprocessed segments. */ void FlowForceReassembly(void) { /* Do remember. We need to have packet acquire disabled by now */ /** ----- Part 1 ------*/ /* Flush out unattended packets */ FlowForceReassemblyFlushPendingPseudoPackets(); /** ----- Part 2 ----- **/ /* Check if all threads are idle. We need this so that we have all * packets freeds. As a consequence, no flows are in use */ SCMutexLock(&tv_root_lock); /* all receive threads are part of packet processing threads */ ThreadVars *tv = tv_root[TVT_PPT]; /* we are doing this in order receive -> decode -> ... -> log */ while (tv != NULL) { if (tv->inq != NULL) { /* we wait till we dry out all the inq packets, before we * kill this thread. Do note that you should have disabled * packet acquire by now using TmThreadDisableReceiveThreads()*/ if (!(strlen(tv->inq->name) == strlen("packetpool") && strcasecmp(tv->inq->name, "packetpool") == 0)) { PacketQueue *q = &trans_q[tv->inq->id]; while (q->len != 0) { usleep(100); } TmThreadsSetFlag(tv, THV_PAUSE); if (tv->inq->q_type == 0) SCCondSignal(&trans_q[tv->inq->id].cond_q); else SCCondSignal(&data_queues[tv->inq->id].cond_q); while (!TmThreadsCheckFlag(tv, THV_PAUSED)) { if (tv->inq->q_type == 0) SCCondSignal(&trans_q[tv->inq->id].cond_q); else SCCondSignal(&data_queues[tv->inq->id].cond_q); usleep(100); } TmThreadsUnsetFlag(tv, THV_PAUSE); } } tv = tv->next; } SCMutexUnlock(&tv_root_lock); /** ----- Part 3 ----- **/ /* Carry out flow reassembly for unattended flows */ FlowForceReassemblyForHash(); return; }
/** * \brief Force reassembly for all the flows that have unprocessed segments. */ void FlowForceReassembly(void) { /* Carry out flow reassembly for unattended flows */ FlowForceReassemblyForHash(); return; }