@ -1,4 +1,4 @@
/* Copyright (C) 2007-201 3 Open Information Security Foundation
/* Copyright (C) 2007-201 7 Open Information Security Foundation
*
*
* You can copy , redistribute or modify this Program under the terms of
* You can copy , redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* the GNU General Public License version 2 as published by the Free
@ -70,6 +70,21 @@ __thread uint64_t rwr_lock_cnt;
# define cpu_set_t cpuset_t
# define cpu_set_t cpuset_t
# endif /* OS_FREEBSD */
# 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 */
/* prototypes */
static int SetCPUAffinity ( uint16_t cpu ) ;
static int SetCPUAffinity ( uint16_t cpu ) ;
@ -214,7 +229,7 @@ static int TmThreadTimeoutLoop(ThreadVars *tv, TmSlot *s)
run = 0 ;
run = 0 ;
}
}
} else {
} else {
usleep ( 1 ) ;
SleepUsec ( 1 ) ;
}
}
if ( tv - > stream_pq - > len = = 0 & & TmThreadsCheckFlag ( tv , THV_KILL ) ) {
if ( tv - > stream_pq - > len = = 0 & & TmThreadsCheckFlag ( tv , THV_KILL ) ) {
@ -1511,17 +1526,14 @@ static int TmThreadKillThread(ThreadVars *tv)
*/
*/
static void TmThreadDrainPacketThreads ( void )
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 ;
ThreadVars * tv = NULL ;
struct timeval start_ts ;
struct timeval cur_ts ;
gettimeofday ( & start_ts , NULL ) ;
again :
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 "
SCLogWarning ( SC_ERR_SHUTDOWN , " unable to get all packet threads "
" to process their packets in time " ) ;
" to process their packets in time " ) ;
return ;
return ;
@ -1531,7 +1543,6 @@ again:
/* all receive threads are part of packet processing threads */
/* all receive threads are part of packet processing threads */
tv = tv_root [ TVT_PPT ] ;
tv = tv_root [ TVT_PPT ] ;
while ( tv ) {
while ( tv ) {
if ( tv - > inq ! = NULL ) {
if ( tv - > inq ! = NULL ) {
/* we wait till we dry out all the inq packets, before we
/* we wait till we dry out all the inq packets, before we
@ -1543,10 +1554,8 @@ again:
if ( q - > len ! = 0 ) {
if ( q - > len ! = 0 ) {
SCMutexUnlock ( & tv_root_lock ) ;
SCMutexUnlock ( & tv_root_lock ) ;
total_wait_time + = WAIT_TIME ;
/* sleep outside lock */
SleepMsec ( 1 ) ;
/* don't sleep while holding a lock */
usleep ( WAIT_TIME ) ;
goto again ;
goto again ;
}
}
}
}
@ -1557,9 +1566,6 @@ again:
SCMutexUnlock ( & tv_root_lock ) ;
SCMutexUnlock ( & tv_root_lock ) ;
return ;
return ;
# undef THREAD_KILL_MAX_WAIT_TIME
# undef WAIT_TIME
}
}
/**
/**
@ -1571,16 +1577,18 @@ again:
*/
*/
void TmThreadDisableReceiveThreads ( void )
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 ;
ThreadVars * tv = NULL ;
struct timeval start_ts ;
struct timeval cur_ts ;
gettimeofday ( & start_ts , NULL ) ;
again :
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 ) ;
SCMutexLock ( & tv_root_lock ) ;
/* all receive threads are part of packet processing threads */
/* all receive threads are part of packet processing threads */
@ -1618,7 +1626,7 @@ again:
if ( q - > len ! = 0 ) {
if ( q - > len ! = 0 ) {
SCMutexUnlock ( & tv_root_lock ) ;
SCMutexUnlock ( & tv_root_lock ) ;
/* don't sleep while holding a lock */
/* don't sleep while holding a lock */
usleep( 1000 ) ;
SleepMsec( 1 ) ;
goto again ;
goto again ;
}
}
}
}
@ -1645,14 +1653,7 @@ again:
while ( ! TmThreadsCheckFlag ( tv , THV_FLOW_LOOP ) ) {
while ( ! TmThreadsCheckFlag ( tv , THV_FLOW_LOOP ) ) {
SCMutexUnlock ( & tv_root_lock ) ;
SCMutexUnlock ( & tv_root_lock ) ;
usleep ( WAIT_TIME ) ;
SleepMsec ( 1 ) ;
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 ) ;
}
goto again ;
goto again ;
}
}
}
}
@ -1675,18 +1676,20 @@ again:
*/
*/
void TmThreadDisablePacketThreads ( void )
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 ;
ThreadVars * tv = NULL ;
struct timeval start_ts ;
struct timeval cur_ts ;
gettimeofday ( & start_ts , NULL ) ;
/* first drain all packet threads of their packets */
/* first drain all packet threads of their packets */
TmThreadDrainPacketThreads ( ) ;
TmThreadDrainPacketThreads ( ) ;
again :
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 ) ;
SCMutexLock ( & tv_root_lock ) ;
/* all receive threads are part of packet processing threads */
/* all receive threads are part of packet processing threads */
@ -1707,7 +1710,7 @@ again:
if ( q - > len ! = 0 ) {
if ( q - > len ! = 0 ) {
SCMutexUnlock ( & tv_root_lock ) ;
SCMutexUnlock ( & tv_root_lock ) ;
/* don't sleep while holding a lock */
/* don't sleep while holding a lock */
usleep( 1000 ) ;
SleepMsec( 1 ) ;
goto again ;
goto again ;
}
}
}
}
@ -1731,14 +1734,7 @@ again:
while ( ! TmThreadsCheckFlag ( tv , THV_RUNNING_DONE ) ) {
while ( ! TmThreadsCheckFlag ( tv , THV_RUNNING_DONE ) ) {
SCMutexUnlock ( & tv_root_lock ) ;
SCMutexUnlock ( & tv_root_lock ) ;
usleep ( WAIT_TIME ) ;
SleepMsec ( 1 ) ;
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 ) ;
}
goto again ;
goto again ;
}
}
@ -1782,10 +1778,11 @@ TmSlot *TmThreadGetFirstTmSlotForPartialPattern(const char *tm_name)
}
}
# define MIN_WAIT_TIME 100
# define MIN_WAIT_TIME 100
# define MAX_WAIT_TIME 999999
void TmThreadKillThreadsFamily ( int family )
void TmThreadKillThreadsFamily ( int family )
{
{
ThreadVars * tv = NULL ;
ThreadVars * tv = NULL ;
unsigned int sleep = MIN_WAIT_TIME ;
unsigned int sleep _usec = MIN_WAIT_TIME ;
BUG_ON ( ( family < 0 ) | | ( family > = TVT_MAX ) ) ;
BUG_ON ( ( family < 0 ) | | ( family > = TVT_MAX ) ) ;
@ -1797,16 +1794,19 @@ again:
int r = TmThreadKillThread ( tv ) ;
int r = TmThreadKillThread ( tv ) ;
if ( r = = 0 ) {
if ( r = = 0 ) {
SCMutexUnlock ( & tv_root_lock ) ;
SCMutexUnlock ( & tv_root_lock ) ;
usleep ( sleep ) ;
SleepUsec ( sleep_usec ) ;
sleep + = MIN_WAIT_TIME ; /* slowly back off */
sleep_usec * = 2 ; /* slowly back off */
sleep_usec = MIN ( sleep_usec , MAX_WAIT_TIME ) ;
goto again ;
goto again ;
}
}
sleep = MIN_WAIT_TIME ; /* reset */
sleep _usec = MIN_WAIT_TIME ; /* reset */
tv = tv - > next ;
tv = tv - > next ;
}
}
SCMutexUnlock ( & tv_root_lock ) ;
SCMutexUnlock ( & tv_root_lock ) ;
}
}
# undef MIN_WAIT_TIME
# undef MAX_WAIT_TIME
void TmThreadKillThreads ( void )
void TmThreadKillThreads ( void )
{
{
@ -1995,7 +1995,7 @@ static void TmThreadDeinitMC(ThreadVars *tv)
void TmThreadTestThreadUnPaused ( ThreadVars * tv )
void TmThreadTestThreadUnPaused ( ThreadVars * tv )
{
{
while ( TmThreadsCheckFlag ( tv , THV_PAUSE ) ) {
while ( TmThreadsCheckFlag ( tv , THV_PAUSE ) ) {
usleep ( 100 ) ;
SleepUsec ( 100 ) ;
if ( TmThreadsCheckFlag ( tv , THV_KILL ) )
if ( TmThreadsCheckFlag ( tv , THV_KILL ) )
break ;
break ;
@ -2013,7 +2013,7 @@ void TmThreadTestThreadUnPaused(ThreadVars *tv)
void TmThreadWaitForFlag ( ThreadVars * tv , uint16_t flags )
void TmThreadWaitForFlag ( ThreadVars * tv , uint16_t flags )
{
{
while ( ! TmThreadsCheckFlag ( tv , flags ) ) {
while ( ! TmThreadsCheckFlag ( tv , flags ) ) {
usleep ( 100 ) ;
SleepUsec ( 100 ) ;
}
}
return ;
return ;
@ -2125,9 +2125,19 @@ TmEcode TmThreadWaitOnThreadInit(void)
uint16_t mgt_num = 0 ;
uint16_t mgt_num = 0 ;
uint16_t ppt_num = 0 ;
uint16_t ppt_num = 0 ;
uint64_t slept = 0 ;
struct timeval start_ts ;
struct timeval cur_ts ;
gettimeofday ( & start_ts , NULL ) ;
again :
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 ) ;
SCMutexLock ( & tv_root_lock ) ;
for ( i = 0 ; i < TVT_MAX ; i + + ) {
for ( i = 0 ; i < TVT_MAX ; i + + ) {
tv = tv_root [ i ] ;
tv = tv_root [ i ] ;
@ -2144,17 +2154,9 @@ again:
if ( ! ( TmThreadsCheckFlag ( tv , THV_INIT_DONE ) ) ) {
if ( ! ( TmThreadsCheckFlag ( tv , THV_INIT_DONE ) ) ) {
SCMutexUnlock ( & tv_root_lock ) ;
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
/* sleep a little to give the thread some
* time to finish initialization */
* time to finish initialization */
usleep ( 100 ) ;
SleepUsec ( 100 ) ;
slept + = 100 ;
goto again ;
goto again ;
}
}