diff --git a/src/app-layer-detect-proto.c b/src/app-layer-detect-proto.c index 2dc4008435..21281bc45c 100644 --- a/src/app-layer-detect-proto.c +++ b/src/app-layer-detect-proto.c @@ -304,6 +304,8 @@ void *AppLayerDetectProtoThread(void *td) StreamMsgQueueSetMinInitChunkLen(FLOW_PKT_TOSERVER, INSPECT_BYTES); StreamMsgQueueSetMinInitChunkLen(FLOW_PKT_TOCLIENT, INSPECT_BYTES); + tv->flags |= THV_INIT_DONE; + /* main loop */ while(run) { TmThreadTestThreadUnPaused(tv); @@ -361,8 +363,10 @@ void *AppLayerDetectProtoThread(void *td) StreamMsgReturnToPool(smsg); } - if (tv->flags & THV_KILL) + if (tv->flags & THV_KILL) { + PerfUpdateCounterArray(tv->pca, &tv->pctx, 0); run = 0; + } } pthread_exit((void *) 0); diff --git a/src/counters.c b/src/counters.c index 009f06e47f..2baf35aafd 100644 --- a/src/counters.c +++ b/src/counters.c @@ -144,6 +144,7 @@ void * PerfMgmtThread(void *arg) return NULL; } + tv_local->flags |= THV_INIT_DONE; while (run) { TmThreadTestThreadUnPaused(tv_local); @@ -183,6 +184,7 @@ void * PerfWakeupThread(void *arg) printf("PerfWakeupThread: spawned\n"); + tv_local->flags |= THV_INIT_DONE; while (run) { TmThreadTestThreadUnPaused(tv_local); diff --git a/src/eidps.c b/src/eidps.c index 6fa677a768..5a32d89011 100644 --- a/src/eidps.c +++ b/src/eidps.c @@ -1594,12 +1594,15 @@ int main(int argc, char **argv) /* Spawn the L7 App Detect thread */ AppLayerDetectProtoThreadSpawn(); - /* Spawn the perf counter threads */ + /* Spawn the perf counter threads. Let these be the last one spawned */ PerfSpawnThreads(); /* Check if the alloted queues have at least 1 reader and writer */ TmValidateQueueState(); + /* Waits till all the threads have been initialized */ + TmThreadWaitOnThreadInit(); + /* Un-pause all the paused threads */ TmThreadContinueThreads(); diff --git a/src/flow.c b/src/flow.c index e110090a78..21c9496cb4 100644 --- a/src/flow.c +++ b/src/flow.c @@ -495,6 +495,7 @@ void *FlowManagerThread(void *td) printf("%s started...\n", th_v->name); + th_v->flags |= THV_INIT_DONE; while (1) { TmThreadTestThreadUnPaused(th_v); @@ -553,6 +554,7 @@ void *FlowManagerThread(void *td) } if (th_v->flags & THV_KILL) { + PerfUpdateCounterArray(th_v->pca, &th_v->pctx, 0); break; } diff --git a/src/threadvars.h b/src/threadvars.h index d8add8727a..d0d161aed3 100644 --- a/src/threadvars.h +++ b/src/threadvars.h @@ -8,11 +8,12 @@ #include "counters.h" /** Thread flags set and read by threads to control the threads */ -#define THV_USE 0x01 /** thread is in use */ -#define THV_PAUSE 0x02 /** thread has been paused */ -#define THV_KILL 0x04 /** thread has been asked to cleanup and exit */ -#define THV_FAILED 0x08 /** thread has encountered an error and failed */ -#define THV_CLOSED 0x10 /** thread done, should be joinable */ +#define THV_USE 0x01 /** thread is in use */ +#define THV_INIT_DONE 0x02 /** thread initialization done */ +#define THV_PAUSE 0x04 /** thread has been paused */ +#define THV_KILL 0x08 /** thread has been asked to cleanup and exit */ +#define THV_FAILED 0x10 /** thread has encountered an error and failed */ +#define THV_CLOSED 0x20 /** thread done, should be joinable */ /** Thread flags set and read by threads, to control the threads, when they encounter certain conditions like failure */ diff --git a/src/tm-threads.c b/src/tm-threads.c index 8196600dfe..e05c170440 100644 --- a/src/tm-threads.c +++ b/src/tm-threads.c @@ -81,6 +81,7 @@ void *TmThreadsSlot1NoIn(void *td) { } memset(&s->s.slot_pq, 0, sizeof(PacketQueue)); + tv->flags |= THV_INIT_DONE; while(run) { TmThreadTestThreadUnPaused(tv); @@ -101,8 +102,10 @@ void *TmThreadsSlot1NoIn(void *td) { tv->tmqh_out(tv, p); - if (tv->flags & THV_KILL) + if (tv->flags & THV_KILL) { + PerfUpdateCounterArray(tv->pca, &tv->pctx, 0); run = 0; + } } if (s->s.SlotThreadExitPrintStats != NULL) { @@ -142,6 +145,7 @@ void *TmThreadsSlot1NoOut(void *td) { } memset(&s->s.slot_pq, 0, sizeof(PacketQueue)); + tv->flags |= THV_INIT_DONE; while(run) { TmThreadTestThreadUnPaused(tv); @@ -156,8 +160,10 @@ void *TmThreadsSlot1NoOut(void *td) { break; } - if (tv->flags & THV_KILL) + if (tv->flags & THV_KILL) { + PerfUpdateCounterArray(tv->pca, &tv->pctx, 0); run = 0; + } } if (s->s.SlotThreadExitPrintStats != NULL) { @@ -198,6 +204,7 @@ void *TmThreadsSlot1NoInOut(void *td) { } memset(&s->s.slot_pq, 0, sizeof(PacketQueue)); + tv->flags |= THV_INIT_DONE; while(run) { TmThreadTestThreadUnPaused(tv); @@ -212,6 +219,7 @@ void *TmThreadsSlot1NoInOut(void *td) { if (tv->flags & THV_KILL) { //printf("%s: TmThreadsSlot1NoInOut: KILL is set\n", tv->name); + PerfUpdateCounterArray(tv->pca, &tv->pctx, 0); run = 0; } } @@ -256,6 +264,7 @@ void *TmThreadsSlot1(void *td) { } memset(&s->s.slot_pq, 0, sizeof(PacketQueue)); + tv->flags |= THV_INIT_DONE; while(run) { TmThreadTestThreadUnPaused(tv); @@ -289,6 +298,7 @@ void *TmThreadsSlot1(void *td) { if (tv->flags & THV_KILL) { //printf("%s: TmThreadsSlot1: KILL is set\n", tv->name); + PerfUpdateCounterArray(tv->pca, &tv->pctx, 0); run = 0; } } @@ -375,6 +385,7 @@ void *TmThreadsSlotVar(void *td) { memset(&slot->slot_pq, 0, sizeof(PacketQueue)); } + tv->flags |= THV_INIT_DONE; while(run) { TmThreadTestThreadUnPaused(tv); @@ -400,6 +411,7 @@ void *TmThreadsSlotVar(void *td) { if (tv->flags & THV_KILL) { //printf("%s: TmThreadsSlot1: KILL is set\n", tv->name); + PerfUpdateCounterArray(tv->pca, &tv->pctx, 0); run = 0; } } @@ -1033,3 +1045,24 @@ void TmThreadCheckThreadState(void) return; } + +/** \brief Used to check if all threads have finished their initialization. On + * finding an un-initialized thread, it waits till that thread completes + * its initialization, before proceeding to the next thread. + */ +void TmThreadWaitOnThreadInit(void) +{ + ThreadVars *tv = NULL; + int i = 0; + + for (i = 0; i < TVT_MAX; i++) { + tv = tv_root[i]; + while (tv != NULL) { + while (!(tv->flags & THV_INIT_DONE)) + ; + tv = tv->next; + } + } + + return; +} diff --git a/src/tm-threads.h b/src/tm-threads.h index b990847a81..6fb21e879c 100644 --- a/src/tm-threads.h +++ b/src/tm-threads.h @@ -50,5 +50,7 @@ void TmThreadPauseThreads(void); void TmThreadCheckThreadState(void); +void TmThreadWaitOnThreadInit(void); + #endif /* __TM_THREADS_H__ */