예제 #1
0
static bool init_thread_lua_state(struct thread_state *state)
{
	int h;
	LUA_STACK_MARK(state->lua->L);

	if (state->pool->attach_debugger > state->attach_debugger) {
		luadebug_debugger_start(state->lua->L, false);
	}
	state->pool->attach_debugger = state->attach_debugger;

	lua_pushcfunction(state->lua->L, lua_state_error_formater);
	h = lua_gettop(state->lua->L);

	lua_getglobal(state->lua->L, "require");
	lua_pushstring(state->lua->L, "rule");
	if (lua_pcall(state->lua->L, 1, 0, h)) {
		lua_state_print_error(state->lua->L, "init");
		lua_pop(state->lua->L, 1);

		LUA_STACK_CHECK(state->lua->L, 0);
		return false;
	}

	if (!lua_state_run_file(state->lua, get_configuration_script(), 0, NULL)) {
		lua_pop(state->lua->L, 1);
		return false;
	}

	lua_getglobal(state->lua->L, "haka");
	lua_getfield(state->lua->L, -1, "rule_summary");
	if (lua_pcall(state->lua->L, 0, 0, h)) {
		lua_state_print_error(state->lua->L, "init");
		lua_pop(state->lua->L, 1);

		LUA_STACK_CHECK(state->lua->L, 0);
		return false;
	}
	lua_pop(state->lua->L, 2);

	LUA_STACK_CHECK(state->lua->L, 0);
	return true;
}
예제 #2
0
static void *thread_main_loop(void *_state)
{
	struct thread_state *state = (struct thread_state *)_state;
	struct packet *pkt = NULL;
	sigset_t set;
#ifdef HAKA_MEMCHECK
	int64 pkt_count=0;
	const int mem_rate=10;
#endif

	thread_setid(state->thread_id);

	if (!state->pool->single) {
		/* Block all signal to let the main thread handle them */
		sigfillset(&set);
		sigdelset(&set, SIGSEGV);
		sigdelset(&set, SIGILL);
		sigdelset(&set, SIGFPE);

		if (!thread_sigmask(SIG_BLOCK, &set, NULL)) {
			LOG_FATAL(core, "%s", clear_error());
			barrier_wait(&state->pool->thread_start_sync);
			state->state = STATE_ERROR;
			return NULL;
		}

		if (!timer_init_thread()) {
			LOG_FATAL(core, "%s", clear_error());
			barrier_wait(&state->pool->thread_start_sync);
			state->state = STATE_ERROR;
			return NULL;
		}

		/* To make sure we can still cancel even if some thread are locked in
		 * infinite loops */
		if (!thread_setcanceltype(THREAD_CANCEL_ASYNCHRONOUS)) {
			LOG_FATAL(core, "%s", clear_error());
			barrier_wait(&state->pool->thread_start_sync);
			state->state = STATE_ERROR;
			return NULL;
		}

		if (!init_thread_lua_state(state)) {
			barrier_wait(&state->pool->thread_start_sync);
			state->state = STATE_ERROR;
			return NULL;
		}
	}

	state->engine = engine_thread_init(state->lua->L, state->thread_id);
	engine_thread_update_status(state->engine, THREAD_RUNNING);

	packet_init(state->capture);

	if (!state->pool->single) {
		if (!barrier_wait(&state->pool->thread_start_sync)) {
			LOG_FATAL(core, "%s", clear_error());
			state->state = STATE_ERROR;
			engine_thread_update_status(state->engine, THREAD_DEFUNC);
			return NULL;
		}
	}

	if (!state->pool->single) {
		if (!barrier_wait(&state->pool->thread_sync)) {
			LOG_FATAL(core, "%s", clear_error());
			state->state = STATE_ERROR;
			engine_thread_update_status(state->engine, THREAD_DEFUNC);
			return NULL;
		}
	}

	lua_state_trigger_haka_event(state->lua, "started");

	engine_thread_update_status(state->engine, THREAD_WAITING);

	while (packet_receive(state->engine, &pkt) == 0) {
		engine_thread_update_status(state->engine, THREAD_RUNNING);

		/* The packet can be NULL in case of failure in packet receive */
		if (pkt) {
			filter_wrapper(state, pkt);
			pkt = NULL;
		}

		lua_state_runinterrupt(state->lua);
		engine_thread_check_remote_launch(state->engine);

		if (state->pool->attach_debugger > state->attach_debugger) {
			luadebug_debugger_start(state->lua->L, true);
			state->attach_debugger = state->pool->attach_debugger;
		}

		engine_thread_update_status(state->engine, THREAD_WAITING);

#ifdef HAKA_MEMCHECK
		if (((pkt_count++) % mem_rate) == 0) {
			size_t vmsize, rss;
			if (!get_memory_size(&vmsize, &rss)) {
				LOG_ERROR(core, "cannot get memory report: %s", clear_error());
			}
			else {
				const size_t luasize = lua_gc(state->lua->L, LUA_GCCOUNT, 0);
				LOG_DEBUG(core, "memory report: thread=%d vmsize=%zd rsssize=%zd luasize=%zd",
						engine_thread_id(state->engine), vmsize, rss, luasize);
			}
		}
#endif

		if (state->pool->stop) {
			break;
		}
	}

	state->state = STATE_FINISHED;
	engine_thread_update_status(state->engine, THREAD_STOPPED);

	return NULL;
}
예제 #3
0
static void *thread_main_loop(void *_state)
{
	struct thread_state *state = (struct thread_state *)_state;
	struct packet *pkt = NULL;
	sigset_t set;

	thread_setid(state->thread_id);

	if (!state->pool->single) {
		/* Block all signal to let the main thread handle them */
		sigfillset(&set);
		sigdelset(&set, SIGSEGV);
		sigdelset(&set, SIGILL);
		sigdelset(&set, SIGFPE);

		if (!thread_sigmask(SIG_BLOCK, &set, NULL)) {
			message(HAKA_LOG_FATAL, "core", clear_error());
			barrier_wait(&state->pool->thread_start_sync);
			state->state = STATE_ERROR;
			return NULL;
		}

		if (!timer_init_thread()) {
			message(HAKA_LOG_FATAL, "core", clear_error());
			barrier_wait(&state->pool->thread_start_sync);
			state->state = STATE_ERROR;
			return NULL;
		}

		/* To make sure we can still cancel even if some thread are locked in
		 * infinite loops */
		if (!thread_setcanceltype(THREAD_CANCEL_ASYNCHRONOUS)) {
			message(HAKA_LOG_FATAL, "core", clear_error());
			barrier_wait(&state->pool->thread_start_sync);
			state->state = STATE_ERROR;
			return NULL;
		}

		if (!init_thread_lua_state(state)) {
			barrier_wait(&state->pool->thread_start_sync);
			state->state = STATE_ERROR;
			return NULL;
		}
	}

	state->engine = engine_thread_init(state->lua->L, state->thread_id);
	engine_thread_update_status(state->engine, THREAD_RUNNING);

	packet_init(state->capture);

	if (!state->pool->single) {
		if (!barrier_wait(&state->pool->thread_start_sync)) {
			message(HAKA_LOG_FATAL, "core", clear_error());
			state->state = STATE_ERROR;
			engine_thread_update_status(state->engine, THREAD_DEFUNC);
			return NULL;
		}
	}

	if (!state->pool->single) {
		if (!barrier_wait(&state->pool->thread_sync)) {
			message(HAKA_LOG_FATAL, "core", clear_error());
			state->state = STATE_ERROR;
			engine_thread_update_status(state->engine, THREAD_DEFUNC);
			return NULL;
		}
	}

	lua_state_trigger_haka_event(state->lua, "started");

	engine_thread_update_status(state->engine, THREAD_WAITING);

	while (packet_receive(&pkt) == 0) {
		engine_thread_update_status(state->engine, THREAD_RUNNING);

		/* The packet can be NULL in case of failure in packet receive */
		if (pkt) {
			filter_wrapper(state, pkt);
			pkt = NULL;
		}

		lua_state_runinterrupt(state->lua);
		engine_thread_check_remote_launch(state->engine);

		if (state->pool->attach_debugger > state->attach_debugger) {
			luadebug_debugger_start(state->lua->L, true);
			state->attach_debugger = state->pool->attach_debugger;
		}

		engine_thread_update_status(state->engine, THREAD_WAITING);

		if (state->pool->stop) {
			break;
		}
	}

	state->state = STATE_FINISHED;
	engine_thread_update_status(state->engine, THREAD_STOPPED);

	return NULL;
}