} FlowTimeoutCounters;
/**
- * \brief Used to kill flow manager thread(s).
+ * \brief Used to disable flow manager thread(s).
*
* \todo Kinda hackish since it uses the tv name to identify flow manager
* thread. We need an all weather identification scheme.
*/
-void FlowKillFlowManagerThread(void)
+void FlowDisableFlowManagerThread(void)
{
ThreadVars *tv = NULL;
int cnt = 0;
while (tv != NULL) {
if (strcasecmp(tv->name, "FlowManagerThread") == 0) {
TmThreadsSetFlag(tv, THV_KILL);
- TmThreadsSetFlag(tv, THV_DEINIT);
cnt++;
+
+ /* value in seconds */
+#define THREAD_KILL_MAX_WAIT_TIME 60
+ /* value in microseconds */
+#define WAIT_TIME 100
+
+ double total_wait_time = 0;
+ while (!TmThreadsCheckFlag(tv, THV_RUNNING_DONE)) {
+ usleep(WAIT_TIME);
+ total_wait_time += WAIT_TIME / 1000000.0;
+ if (total_wait_time > THREAD_KILL_MAX_WAIT_TIME) {
+ SCLogError(SC_ERR_FATAL, "Engine unable to "
+ "disable detect thread - \"%s\". "
+ "Killing engine", tv->name);
+ exit(EXIT_FAILURE);
+ }
+ }
}
tv = tv->next;
}
for (u = 0; u < flowmgr_number; u++)
SCCtrlCondSignal(&flow_manager_ctrl_cond);
- tv = tv_root[TVT_MGMT];
- while (tv != NULL) {
- if (strcasecmp(tv->name, "FlowManagerThread") == 0) {
- /* be sure it has shut down */
- while (!TmThreadsCheckFlag(tv, THV_CLOSED)) {
- usleep(100);
- }
- }
- tv = tv->next;
- }
-
-
- /* not possible, unless someone decides to rename FlowManagerThread */
- if (cnt == 0) {
- SCMutexUnlock(&tv_root_lock);
- abort();
- }
-
SCMutexUnlock(&tv_root_lock);
/* reset count, so we can kill and respawn (unix socket) */
}
/**
- * \brief Used to kill flow recycler thread(s).
+ * \brief Used to disable flow recycler thread(s).
*
* \note this should only be called when the flow manager is already gone
*
* \todo Kinda hackish since it uses the tv name to identify flow recycler
* thread. We need an all weather identification scheme.
*/
-void FlowKillFlowRecyclerThread(void)
+void FlowDisableFlowRecyclerThread(void)
{
ThreadVars *tv = NULL;
int cnt = 0;
while (tv != NULL) {
if (strcasecmp(tv->name, "FlowRecyclerThread") == 0) {
TmThreadsSetFlag(tv, THV_KILL);
- TmThreadsSetFlag(tv, THV_DEINIT);
cnt++;
+
+ /* value in seconds */
+#define THREAD_KILL_MAX_WAIT_TIME 60
+ /* value in microseconds */
+#define WAIT_TIME 100
+
+ double total_wait_time = 0;
+ while (!TmThreadsCheckFlag(tv, THV_RUNNING_DONE)) {
+ usleep(WAIT_TIME);
+ total_wait_time += WAIT_TIME / 1000000.0;
+ if (total_wait_time > THREAD_KILL_MAX_WAIT_TIME) {
+ SCLogError(SC_ERR_FATAL, "Engine unable to "
+ "disable detect thread - \"%s\". "
+ "Killing engine", tv->name);
+ exit(EXIT_FAILURE);
+ }
+ }
}
tv = tv->next;
}
for (u = 0; u < flowrec_number; u++)
SCCtrlCondSignal(&flow_recycler_ctrl_cond);
- tv = tv_root[TVT_MGMT];
- while (tv != NULL) {
- if (strcasecmp(tv->name, "FlowRecyclerThread") == 0) {
- /* be sure it has shut down */
- while (!TmThreadsCheckFlag(tv, THV_CLOSED)) {
- usleep(100);
- }
- }
- tv = tv->next;
- }
-
-
- /* not possible, unless someone decides to rename FlowManagerThread */
- if (cnt == 0) {
- SCMutexUnlock(&tv_root_lock);
- abort();
- }
-
SCMutexUnlock(&tv_root_lock);
/* reset count, so we can kill and respawn (unix socket) */
}
this->currentfile = NULL;
+ /* needed by FlowForceReassembly */
+ PacketPoolInit();
+
/* handle graceful shutdown of the flow engine, it's helper
* threads and the packet threads */
- FlowKillFlowManagerThread();
+ FlowDisableFlowManagerThread();
TmThreadDisableReceiveThreads();
FlowForceReassembly();
TmThreadDisablePacketThreads();
- FlowKillFlowRecyclerThread();
+ FlowDisableFlowRecyclerThread();
/* kill the stats threads */
TmThreadKillThreadsFamily(TVT_MGMT);
TmThreadKillThreadsFamily(TVT_PPT);
TmThreadClearThreadsFamily(TVT_PPT);
+ PacketPoolDestroy();
+
/* mgt and ppt threads killed, we can run non thread-safe
* shutdown functions */
SCPerfReleaseResources();
UnixSocketKillSocketThread();
if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
- /* First we need to kill the flow manager thread */
- FlowKillFlowManagerThread();
+ /* First we need to disable the flow manager thread */
+ FlowDisableFlowManagerThread();
}
+
/* Disable packet acquisition first */
TmThreadDisableReceiveThreads();
if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
+ /* we need a packet pool for FlowForceReassembly */
+ PacketPoolInit();
+
FlowForceReassembly();
/* kill receive threads when they have processed all
* flow timeout packets */
/* before TmThreadKillThreads, as otherwise that kills it
* but more slowly */
if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
- FlowKillFlowRecyclerThread();
+ FlowDisableFlowRecyclerThread();
}
/* kill remaining threads */
TmThreadKillThreads();
+
if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
+ /* destroy the packet pool for flow reassembly after all
+ * the other threads are gone. */
+ PacketPoolDestroy();
+
SCPerfReleaseResources();
IPPairShutdown();
FlowShutdown();