Пример #1
0
/** the background thread func */
static void*
libworker_dobg(void* arg)
{
	/* setup */
	uint32_t m;
	struct libworker* w = (struct libworker*)arg;
	struct ub_ctx* ctx;
	if(!w) {
		log_err("libunbound bg worker init failed, nomem");
		return NULL;
	}
	ctx = w->ctx;
	log_thread_set(&w->thread_num);
#ifdef THREADS_DISABLED
	/* we are forked */
	w->is_bg_thread = 0;
	/* close non-used parts of the pipes */
	tube_close_write(ctx->qq_pipe);
	tube_close_read(ctx->rr_pipe);
#endif
	if(!tube_setup_bg_listen(ctx->qq_pipe, w->base, 
		libworker_handle_control_cmd, w)) {
		log_err("libunbound bg worker init failed, no bglisten");
		return NULL;
	}
	if(!tube_setup_bg_write(ctx->rr_pipe, w->base)) {
		log_err("libunbound bg worker init failed, no bgwrite");
		return NULL;
	}

	/* do the work */
	comm_base_dispatch(w->base);

	/* cleanup */
	m = UB_LIBCMD_QUIT;
	w->want_quit = 1;
	tube_remove_bg_listen(w->ctx->qq_pipe);
	tube_remove_bg_write(w->ctx->rr_pipe);
	libworker_delete(w);
	(void)tube_write_msg(ctx->rr_pipe, (uint8_t*)&m, 
		(uint32_t)sizeof(m), 0);
#ifdef THREADS_DISABLED
	/* close pipes from forked process before exit */
	tube_close_read(ctx->qq_pipe);
	tube_close_write(ctx->rr_pipe);
#endif
	return NULL;
}
Пример #2
0
/**
 * Function to start one thread. 
 * @param arg: user argument.
 * @return: void* user return value could be used for thread_join results.
 */
static void* 
thread_start(void* arg)
{
	struct worker* worker = (struct worker*)arg;
	int port_num = 0;
	log_thread_set(&worker->thread_num);
	ub_thread_blocksigs();
#ifdef THREADS_DISABLED
	/* close pipe ends used by main */
	tube_close_write(worker->cmd);
	close_other_pipes(worker->daemon, worker->thread_num);
#endif
#ifdef SO_REUSEPORT
	if(worker->daemon->cfg->so_reuseport)
		port_num = worker->thread_num % worker->daemon->num_ports;
	else
		port_num = 0;
#endif
	if(!worker_init(worker, worker->daemon->cfg,
			worker->daemon->ports[port_num], 0))
		fatal_exit("Could not initialize thread");

	worker_work(worker);
	return NULL;
}
Пример #3
0
int libworker_bg(struct ub_ctx* ctx)
{
	struct libworker* w;
	/* fork or threadcreate */
	lock_basic_lock(&ctx->cfglock);
	if(ctx->dothread) {
		lock_basic_unlock(&ctx->cfglock);
		w = libworker_setup(ctx, 1, NULL);
		if(!w) return UB_NOMEM;
		w->is_bg_thread = 1;
#ifdef ENABLE_LOCK_CHECKS
		w->thread_num = 1; /* for nicer DEBUG checklocks */
#endif
		ub_thread_create(&ctx->bg_tid, libworker_dobg, w);
	} else {
		lock_basic_unlock(&ctx->cfglock);
#ifndef HAVE_FORK
		/* no fork on windows */
		return UB_FORKFAIL;
#else /* HAVE_FORK */
		switch((ctx->bg_pid=fork())) {
			case 0:
				w = libworker_setup(ctx, 1, NULL);
				if(!w) fatal_exit("out of memory");
				/* close non-used parts of the pipes */
				tube_close_write(ctx->qq_pipe);
				tube_close_read(ctx->rr_pipe);
				(void)libworker_dobg(w);
				exit(0);
				break;
			case -1:
				return UB_FORKFAIL;
			default:
				/* close non-used parts, so that the worker
				 * bgprocess gets 'pipe closed' when the
				 * main process exits */
				tube_close_read(ctx->qq_pipe);
				tube_close_write(ctx->rr_pipe);
				break;
		}
#endif /* HAVE_FORK */ 
	}
	return UB_NOERROR;
}
Пример #4
0
void tube_delete(struct tube* tube)
{
	if(!tube) return;
	tube_remove_bg_listen(tube);
	tube_remove_bg_write(tube);
	/* close fds after deleting commpoints, to be sure.
	 *            Also epoll does not like closing fd before event_del */
	tube_close_read(tube);
	tube_close_write(tube);
	free(tube);
}
Пример #5
0
void tube_delete(struct tube* tube)
{
	if(!tube) return;
	tube_remove_bg_listen(tube);
	tube_remove_bg_write(tube);
	tube_close_read(tube);
	tube_close_write(tube);
	if(!WSACloseEvent(tube->event))
		log_err("WSACloseEvent: %s", wsa_strerror(WSAGetLastError()));
	lock_basic_destroy(&tube->res_lock);
	verbose(VERB_ALGO, "tube deleted");
	free(tube);
}