examples/lib/custom: use own custom run mode

Debug validation revealed that library ThreadVars were being
created *after* the threads were sealed. And the only way to create
your ThreadVars that fits within the current application life-cycle is
to create them in your own custom run mode.

This is likely a better model for users who are bringing their own
packets and threads anyways, as they are essentially providing their
own capture method, and all capture methods provide their own run
mode. They're also using their own threads, which means adapting to
their own threading model.

This is suitable for a backport to 8.0. But for 9.0 we can go further
and remove the built-in library run mode, which will be done in a
follow-up commit.

Ticket: #8259
(cherry picked from commit 445de77c71)
pull/15003/head
Jason Ish 2 months ago committed by Victor Julien
parent 4da63239b3
commit b7447b1437

@ -30,6 +30,9 @@
static int worker_id = 1;
/* ThreadVars created during runmode setup, before thread sealing. */
static ThreadVars *g_worker_tv = NULL;
/**
* Struct to pass arguments into a worker thread.
*/
@ -154,6 +157,26 @@ static uint8_t RateFilterCallback(const Packet *p, const uint32_t sid, const uin
return new_action;
}
/**
* Application runmode setup that creates ThreadVars before thread
* sealing. This follows the pattern used by other runmodes (e.g.,
* pcap-file) where threads are registered during the runmode
* callback.
*/
static int AppRunModeSetup(void)
{
/* This example uses pcap files, so set time mode to offline. */
TimeModeSetOffline();
g_worker_tv = SCRunModeLibCreateThreadVars(worker_id++);
if (!g_worker_tv) {
SCLogError("Failed to create ThreadVars");
return -1;
}
return 0;
}
int main(int argc, char **argv)
{
SuricataPreInit(argv[0]);
@ -208,8 +231,13 @@ int main(int argc, char **argv)
* loaded. */
SCEnableDefaultSignalHandlers();
/* Set "offline" runmode to replay a pcap in library mode. */
if (!SCConfSetFromString("runmode=offline", 1)) {
/* Register our own library run mode. At this time, the ThreadVars
* for each capture thread need to be created in the provided
* callback to meet thread synchronization requirements. */
RunModeRegisterNewRunMode(
RUNMODE_LIB, "custom", "Custom application run mode", AppRunModeSetup, NULL);
if (!SCConfSetFromString("runmode=custom", 1)) {
exit(EXIT_FAILURE);
}
@ -221,20 +249,16 @@ int main(int argc, char **argv)
exit(1);
}
/* SuricataInit will call our AppRunModeSetup, when it returns our
* ThreadVars will be ready. */
SuricataInit();
SCDetectEngineRegisterRateFilterCallback(RateFilterCallback, NULL);
/* Create and start worker on its own thread, passing the PCAP
* file as argument. This needs to be done in between SuricataInit
* and SuricataPostInit. */
/* Spawn our worker threads. */
pthread_t worker;
ThreadVars *tv = SCRunModeLibCreateThreadVars(worker_id++);
if (!tv) {
FatalError("Failed to create ThreadVars");
}
struct WorkerArgs args = {
.tv = tv,
.tv = g_worker_tv,
.pcap_filename = argv[argc - 1],
};
if (pthread_create(&worker, NULL, SimpleWorker, &args) != 0) {

Loading…
Cancel
Save