SC_ATOMIC_DECLARE(uint32_t, flowrec_busy);
SC_ATOMIC_EXTERN(unsigned int, flow_flags);
+SCCtrlCondT flow_manager_ctrl_cond;
+SCCtrlMutex flow_manager_ctrl_mutex;
+
void FlowTimeoutsInit(void)
{
SC_ATOMIC_SET(flow_timeouts, flow_timeouts_normal);
if (suricata_ctl_flags != 0)
return TM_ECODE_OK;
}
+ const bool time_is_live = TimeModeIsLive();
SCLogDebug("FM %s/%d starting. min_timeout %us. Full hash pass in %us", th_v->name,
ftd->instance, min_timeout, pass_in_sec);
memset(&sleep_startts, 0, sizeof(sleep_startts));
gettimeofday(&sleep_startts, NULL);
#endif
- usleep(250);
+
+ if (emerg || !time_is_live) {
+ usleep(250);
+ } else {
+ struct timeval cond_tv;
+ gettimeofday(&cond_tv, NULL);
+ struct timeval add_tv;
+ add_tv.tv_sec = 0;
+ add_tv.tv_usec = 667 * 1000;
+ timeradd(&cond_tv, &add_tv, &cond_tv);
+
+ struct timespec cond_time = FROM_TIMEVAL(cond_tv);
+ SCCtrlMutexLock(&flow_manager_ctrl_mutex);
+ while (1) {
+ int rc = SCCtrlCondTimedwait(
+ &flow_manager_ctrl_cond, &flow_manager_ctrl_mutex, &cond_time);
+ if (rc == ETIMEDOUT || rc < 0)
+ break;
+ if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY) {
+ break;
+ }
+ }
+ SCCtrlMutexUnlock(&flow_manager_ctrl_mutex);
+ }
#ifdef FM_PROFILE
struct timeval sleep_endts;
}
flowmgr_number = (uint32_t)setting;
+ SCCtrlCondInit(&flow_manager_ctrl_cond, NULL);
+ SCCtrlMutexInit(&flow_manager_ctrl_mutex, NULL);
+
SCLogConfig("using %u flow manager threads", flowmgr_number);
StatsRegisterGlobalCounter("flow.memuse", FlowGetMemuse);
#ifndef __FLOW_MANAGER_H__
#define __FLOW_MANAGER_H__
+/** flow manager scheduling condition */
+extern SCCtrlCondT flow_manager_ctrl_cond;
+extern SCCtrlMutex flow_manager_ctrl_mutex;
+#define FlowWakeupFlowManagerThread() SCCtrlCondSignal(&flow_manager_ctrl_cond)
+
#define FlowTimeoutsReset() FlowTimeoutsInit()
void FlowTimeoutsInit(void);
void FlowTimeoutsEmergency(void);