-/* Copyright (C) 2007-2013 Open Information Security Foundation
+/* Copyright (C) 2007-2017 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
#define cpu_set_t cpuset_t
#endif /* OS_FREEBSD */
+#ifdef OS_WIN32
+static inline void SleepUsec(uint64_t usec)
+{
+ uint64_t msec = 1;
+ if (usec > 1000) {
+ msec = usec / 1000;
+ }
+ Sleep(msec);
+}
+#define SleepMsec(msec) Sleep((msec))
+#else
+#define SleepUsec(usec) usleep((usec))
+#define SleepMsec(msec) usleep((msec) * 1000)
+#endif
+
/* prototypes */
static int SetCPUAffinity(uint16_t cpu);
run = 0;
}
} else {
- usleep(1);
+ SleepUsec(1);
}
if (tv->stream_pq->len == 0 && TmThreadsCheckFlag(tv, THV_KILL)) {
*/
static void TmThreadDrainPacketThreads(void)
{
- /* value in seconds */
-#define THREAD_KILL_MAX_WAIT_TIME 60
- /* value in microseconds */
-#define WAIT_TIME 1000
-
- uint64_t total_wait_time = 0;
-
ThreadVars *tv = NULL;
+ struct timeval start_ts;
+ struct timeval cur_ts;
+ gettimeofday(&start_ts, NULL);
again:
- if (total_wait_time > (THREAD_KILL_MAX_WAIT_TIME * 1000000)) {
+ gettimeofday(&cur_ts, NULL);
+ if ((cur_ts.tv_sec - start_ts.tv_sec) > 60) {
SCLogWarning(SC_ERR_SHUTDOWN, "unable to get all packet threads "
"to process their packets in time");
return;
/* all receive threads are part of packet processing threads */
tv = tv_root[TVT_PPT];
-
while (tv) {
if (tv->inq != NULL) {
/* we wait till we dry out all the inq packets, before we
if (q->len != 0) {
SCMutexUnlock(&tv_root_lock);
- total_wait_time += WAIT_TIME;
-
- /* don't sleep while holding a lock */
- usleep(WAIT_TIME);
+ /* sleep outside lock */
+ SleepMsec(1);
goto again;
}
}
SCMutexUnlock(&tv_root_lock);
return;
-
-#undef THREAD_KILL_MAX_WAIT_TIME
-#undef WAIT_TIME
}
/**
*/
void TmThreadDisableReceiveThreads(void)
{
- /* value in seconds */
-#define THREAD_KILL_MAX_WAIT_TIME 60
- /* value in microseconds */
-#define WAIT_TIME 100
-
- double total_wait_time = 0;
-
ThreadVars *tv = NULL;
+ struct timeval start_ts;
+ struct timeval cur_ts;
+ gettimeofday(&start_ts, NULL);
again:
+ gettimeofday(&cur_ts, NULL);
+ if ((cur_ts.tv_sec - start_ts.tv_sec) > 60) {
+ FatalError(SC_ERR_FATAL, "Engine unable to disable detect "
+ "thread - \"%s\". Killing engine", tv->name);
+ }
+
SCMutexLock(&tv_root_lock);
/* all receive threads are part of packet processing threads */
if (q->len != 0) {
SCMutexUnlock(&tv_root_lock);
/* don't sleep while holding a lock */
- usleep(1000);
+ SleepMsec(1);
goto again;
}
}
while (!TmThreadsCheckFlag(tv, THV_FLOW_LOOP)) {
SCMutexUnlock(&tv_root_lock);
- 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);
- }
+ SleepMsec(1);
goto again;
}
}
*/
void TmThreadDisablePacketThreads(void)
{
- /* value in seconds */
-#define THREAD_KILL_MAX_WAIT_TIME 60
- /* value in microseconds */
-#define WAIT_TIME 100
-
- double total_wait_time = 0;
-
ThreadVars *tv = NULL;
+ struct timeval start_ts;
+ struct timeval cur_ts;
+ gettimeofday(&start_ts, NULL);
/* first drain all packet threads of their packets */
TmThreadDrainPacketThreads();
again:
+ gettimeofday(&cur_ts, NULL);
+ if ((cur_ts.tv_sec - start_ts.tv_sec) > 60) {
+ FatalError(SC_ERR_FATAL, "Engine unable to disable detect "
+ "thread - \"%s\". Killing engine", tv->name);
+ }
+
SCMutexLock(&tv_root_lock);
/* all receive threads are part of packet processing threads */
if (q->len != 0) {
SCMutexUnlock(&tv_root_lock);
/* don't sleep while holding a lock */
- usleep(1000);
+ SleepMsec(1);
goto again;
}
}
while (!TmThreadsCheckFlag(tv, THV_RUNNING_DONE)) {
SCMutexUnlock(&tv_root_lock);
- 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);
- }
+ SleepMsec(1);
goto again;
}
}
#define MIN_WAIT_TIME 100
+#define MAX_WAIT_TIME 999999
void TmThreadKillThreadsFamily(int family)
{
ThreadVars *tv = NULL;
- unsigned int sleep = MIN_WAIT_TIME;
+ unsigned int sleep_usec = MIN_WAIT_TIME;
BUG_ON((family < 0) || (family >= TVT_MAX));
int r = TmThreadKillThread(tv);
if (r == 0) {
SCMutexUnlock(&tv_root_lock);
- usleep(sleep);
- sleep += MIN_WAIT_TIME; /* slowly back off */
+ SleepUsec(sleep_usec);
+ sleep_usec *= 2; /* slowly back off */
+ sleep_usec = MIN(sleep_usec, MAX_WAIT_TIME);
goto again;
}
- sleep = MIN_WAIT_TIME; /* reset */
+ sleep_usec = MIN_WAIT_TIME; /* reset */
tv = tv->next;
}
SCMutexUnlock(&tv_root_lock);
}
+#undef MIN_WAIT_TIME
+#undef MAX_WAIT_TIME
void TmThreadKillThreads(void)
{
void TmThreadTestThreadUnPaused(ThreadVars *tv)
{
while (TmThreadsCheckFlag(tv, THV_PAUSE)) {
- usleep(100);
+ SleepUsec(100);
if (TmThreadsCheckFlag(tv, THV_KILL))
break;
void TmThreadWaitForFlag(ThreadVars *tv, uint16_t flags)
{
while (!TmThreadsCheckFlag(tv, flags)) {
- usleep(100);
+ SleepUsec(100);
}
return;
uint16_t mgt_num = 0;
uint16_t ppt_num = 0;
- uint64_t slept = 0;
+ struct timeval start_ts;
+ struct timeval cur_ts;
+ gettimeofday(&start_ts, NULL);
again:
+ gettimeofday(&cur_ts, NULL);
+ if ((cur_ts.tv_sec - start_ts.tv_sec) > 120) {
+ SCLogError(SC_ERR_THREAD_INIT, "thread \"%s\" failed to "
+ "initialize in time: flags %04x", tv->name,
+ SC_ATOMIC_GET(tv->flags));
+ return TM_ECODE_FAILED;
+ }
+
SCMutexLock(&tv_root_lock);
for (i = 0; i < TVT_MAX; i++) {
tv = tv_root[i];
if (!(TmThreadsCheckFlag(tv, THV_INIT_DONE))) {
SCMutexUnlock(&tv_root_lock);
- if (slept > (120*1000000)) {
- SCLogError(SC_ERR_THREAD_INIT, "thread \"%s\" failed to "
- "initialize in time: flags %04x", tv->name,
- SC_ATOMIC_GET(tv->flags));
- return TM_ECODE_FAILED;
- }
-
/* sleep a little to give the thread some
* time to finish initialization */
- usleep(100);
- slept += 100;
+ SleepUsec(100);
goto again;
}