Beispiel #1
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;
}
Beispiel #2
0
struct thread_pool *thread_pool_create(int count, struct packet_module *packet_module,
		bool attach_debugger, bool dissector_graph)
{
	int i;
	struct thread_pool *pool;

	assert(count > 0);
	engine_prepare(count);

	pool = malloc(sizeof(struct thread_pool));
	if (!pool) {
		error("memory error");
		return NULL;
	}

	memset(pool, 0, sizeof(struct thread_pool));

	pool->threads = malloc(sizeof(struct thread_state*)*count);
	if (!pool) {
		error("memory error");
		thread_pool_cleanup(pool);
		return NULL;
	}

	memset(pool->threads, 0, sizeof(struct thread_state*)*count);

	pool->count = count;
	pool->single = count == 1;
	pool->stop = false;

	if (!barrier_init(&pool->thread_sync, count+1)) {
		thread_pool_cleanup(pool);
		return NULL;
	}

	if (!barrier_init(&pool->thread_start_sync, 2)) {
		thread_pool_cleanup(pool);
		return NULL;
	}

	if (attach_debugger) {
		thread_pool_attachdebugger(pool);
	}

	for (i=0; i<count; ++i) {
		pool->threads[i] = init_thread_state(packet_module, i, dissector_graph);
		if (!pool->threads[i]) {
			error("thread initialization error");
			thread_pool_cleanup(pool);
			return NULL;
		}

		pool->threads[i]->pool = pool;

		if (pool->single) {
			if (!init_thread_lua_state(pool->threads[i])) {
				error("thread initialization error");
				thread_pool_cleanup(pool);
				return NULL;
			}
		}
		else {
			if (!thread_create(&pool->threads[i]->thread, thread_main_loop, pool->threads[i])) {
				thread_pool_cleanup(pool);
				return NULL;
			}

			pool->threads[i]->state = STATE_RUNNING;

			if (!barrier_wait(&pool->thread_start_sync)) {
				thread_pool_cleanup(pool);
				return NULL;
			}

			if (pool->threads[i]->state == STATE_ERROR) {
				error("thread initialization error");
				thread_pool_cleanup(pool);
				return NULL;
			}
		}
	}

	return pool;
}
Beispiel #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;
}