Exemplo n.º 1
0
Arquivo: app.c Projeto: Distrotech/ntp
isc_result_t
isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
	      void *arg) {
	isc_event_t *event;
	isc_task_t *cloned_task = NULL;
	isc_result_t result;


	LOCK(&lock);
	if (running) {
		result = ISC_R_ALREADYRUNNING;
		goto unlock;
	}

	/*
	 * Note that we store the task to which we're going to send the event
	 * in the event's "sender" field.
	 */
	isc_task_attach(task, &cloned_task);
	event = isc_event_allocate(mctx, cloned_task, ISC_APPEVENT_SHUTDOWN,
				   action, arg, sizeof(*event));
	if (event == NULL) {
		result = ISC_R_NOMEMORY;
		goto unlock;
	}

	ISC_LIST_APPEND(on_run, event, ev_link);
	result = ISC_R_SUCCESS;

 unlock:
	UNLOCK(&lock);
	return (result);
}
Exemplo n.º 2
0
ATF_TC_BODY(get_objects, tc) {
	isc_result_t result;
	isc_pool_t *pool = NULL;
	void *item;
	isc_task_t *task1 = NULL, *task2 = NULL, *task3 = NULL;

	UNUSED(tc);

	result = isc_test_begin(NULL, ISC_TRUE);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = isc_pool_create(mctx, 2, poolfree, poolinit, taskmgr, &pool);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	ATF_REQUIRE_EQ(isc_pool_count(pool), 2);

	item = isc_pool_get(pool);
	ATF_REQUIRE(item != NULL);
	isc_task_attach((isc_task_t *) item, &task1);

	item = isc_pool_get(pool);
	ATF_REQUIRE(item != NULL);
	isc_task_attach((isc_task_t *) item, &task2);

	item = isc_pool_get(pool);
	ATF_REQUIRE(item != NULL);
	isc_task_attach((isc_task_t *) item, &task3);

	isc_task_detach(&task1);
	isc_task_detach(&task2);
	isc_task_detach(&task3);

	isc_pool_destroy(&pool);
	ATF_REQUIRE_EQ(pool, NULL);

	isc_test_end();
}
Exemplo n.º 3
0
isc_result_t
isc_ondestroy_register(isc_ondestroy_t *ondest, isc_task_t *task,
		       isc_event_t **eventp)
{
	isc_event_t *theevent;
	isc_task_t *thetask = NULL;

	REQUIRE(VALID_ONDESTROY(ondest));
	REQUIRE(task != NULL);
	REQUIRE(eventp != NULL);

	theevent = *eventp;

	REQUIRE(theevent != NULL);

	isc_task_attach(task, &thetask);

	theevent->ev_sender = thetask;

	ISC_LIST_APPEND(ondest->events, theevent, ev_link);

	return (ISC_R_SUCCESS);
}
Exemplo n.º 4
0
isc_result_t
isc_httpdmgr_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
		    isc_httpdclientok_t *client_ok,
		    isc_httpdondestroy_t *ondestroy, void *cb_arg,
		    isc_timermgr_t *tmgr, isc_httpdmgr_t **httpdp)
{
	isc_result_t result;
	isc_httpdmgr_t *httpd;

	REQUIRE(mctx != NULL);
	REQUIRE(sock != NULL);
	REQUIRE(task != NULL);
	REQUIRE(tmgr != NULL);
	REQUIRE(httpdp != NULL && *httpdp == NULL);

	httpd = isc_mem_get(mctx, sizeof(isc_httpdmgr_t));
	if (httpd == NULL)
		return (ISC_R_NOMEMORY);

	result = isc_mutex_init(&httpd->lock);
	if (result != ISC_R_SUCCESS) {
		isc_mem_put(mctx, httpd, sizeof(isc_httpdmgr_t));
		return (result);
	}
	httpd->mctx = NULL;
	isc_mem_attach(mctx, &httpd->mctx);
	httpd->sock = NULL;
	isc_socket_attach(sock, &httpd->sock);
	httpd->task = NULL;
	isc_task_attach(task, &httpd->task);
	httpd->timermgr = tmgr; /* XXXMLG no attach function? */
	httpd->client_ok = client_ok;
	httpd->ondestroy = ondestroy;
	httpd->cb_arg = cb_arg;

	ISC_LIST_INIT(httpd->running);
	ISC_LIST_INIT(httpd->urls);

	/* XXXMLG ignore errors on isc_socket_listen() */
	result = isc_socket_listen(sock, SOMAXCONN);
	if (result != ISC_R_SUCCESS) {
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_socket_listen() failed: %s",
				 isc_result_totext(result));
		goto cleanup;
	}

	(void)isc_socket_filter(sock, "httpready");

	result = isc_socket_accept(sock, task, isc_httpd_accept, httpd);
	if (result != ISC_R_SUCCESS)
		goto cleanup;

	httpd->render_404 = render_404;
	httpd->render_500 = render_500;

	*httpdp = httpd;
	return (ISC_R_SUCCESS);

  cleanup:
	isc_task_detach(&httpd->task);
	isc_socket_detach(&httpd->sock);
	isc_mem_detach(&httpd->mctx);
	(void)isc_mutex_destroy(&httpd->lock);
	isc_mem_put(mctx, httpd, sizeof(isc_httpdmgr_t));
	return (result);
}
Exemplo n.º 5
0
ISC_TIMERFUNC_SCOPE isc_result_t
isc__timer_create(isc_timermgr_t *manager0, isc_timertype_t type,
		  isc_time_t *expires, isc_interval_t *interval,
		  isc_task_t *task, isc_taskaction_t action, const void *arg,
		  isc_timer_t **timerp)
{
	isc__timermgr_t *manager = (isc__timermgr_t *)manager0;
	isc__timer_t *timer;
	isc_result_t result;
	isc_time_t now;

	/*
	 * Create a new 'type' timer managed by 'manager'.  The timers
	 * parameters are specified by 'expires' and 'interval'.  Events
	 * will be posted to 'task' and when dispatched 'action' will be
	 * called with 'arg' as the arg value.  The new timer is returned
	 * in 'timerp'.
	 */

	REQUIRE(VALID_MANAGER(manager));
	REQUIRE(task != NULL);
	REQUIRE(action != NULL);
	if (expires == NULL)
		expires = isc_time_epoch;
	if (interval == NULL)
		interval = isc_interval_zero;
	REQUIRE(type == isc_timertype_inactive ||
		!(isc_time_isepoch(expires) && isc_interval_iszero(interval)));
	REQUIRE(timerp != NULL && *timerp == NULL);
	REQUIRE(type != isc_timertype_limited ||
		!(isc_time_isepoch(expires) || isc_interval_iszero(interval)));

	/*
	 * Get current time.
	 */
	if (type != isc_timertype_inactive) {
		TIME_NOW(&now);
	} else {
		/*
		 * We don't have to do this, but it keeps the compiler from
		 * complaining about "now" possibly being used without being
		 * set, even though it will never actually happen.
		 */
		isc_time_settoepoch(&now);
	}


	timer = isc_mem_get(manager->mctx, sizeof(*timer));
	if (timer == NULL)
		return (ISC_R_NOMEMORY);

	timer->manager = manager;
	timer->references = 1;

	if (type == isc_timertype_once && !isc_interval_iszero(interval)) {
		result = isc_time_add(&now, interval, &timer->idle);
		if (result != ISC_R_SUCCESS) {
			isc_mem_put(manager->mctx, timer, sizeof(*timer));
			return (result);
		}
	} else
		isc_time_settoepoch(&timer->idle);

	timer->type = type;
	timer->expires = *expires;
	timer->interval = *interval;
	timer->task = NULL;
	isc_task_attach(task, &timer->task);
	timer->action = action;
	/*
	 * Removing the const attribute from "arg" is the best of two
	 * evils here.  If the timer->arg member is made const, then
	 * it affects a great many recipients of the timer event
	 * which did not pass in an "arg" that was truly const.
	 * Changing isc_timer_create() to not have "arg" prototyped as const,
	 * though, can cause compilers warnings for calls that *do*
	 * have a truly const arg.  The caller will have to carefully
	 * keep track of whether arg started as a true const.
	 */
	DE_CONST(arg, timer->arg);
	timer->index = 0;
	result = isc_mutex_init(&timer->lock);
	if (result != ISC_R_SUCCESS) {
		isc_task_detach(&timer->task);
		isc_mem_put(manager->mctx, timer, sizeof(*timer));
		return (result);
	}
	ISC_LINK_INIT(timer, link);
	timer->common.impmagic = TIMER_MAGIC;
	timer->common.magic = ISCAPI_TIMER_MAGIC;
	timer->common.methods = (isc_timermethods_t *)&timermethods;

	LOCK(&manager->lock);

	/*
	 * Note we don't have to lock the timer like we normally would because
	 * there are no external references to it yet.
	 */

	if (type != isc_timertype_inactive)
		result = schedule(timer, &now, ISC_TRUE);
	else
		result = ISC_R_SUCCESS;
	if (result == ISC_R_SUCCESS)
		APPEND(manager->timers, timer, link);

	UNLOCK(&manager->lock);

	if (result != ISC_R_SUCCESS) {
		timer->common.impmagic = 0;
		timer->common.magic = 0;
		DESTROYLOCK(&timer->lock);
		isc_task_detach(&timer->task);
		isc_mem_put(manager->mctx, timer, sizeof(*timer));
		return (result);
	}

	*timerp = (isc_timer_t *)timer;

	return (ISC_R_SUCCESS);
}
Exemplo n.º 6
0
isc_result_t
ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
		       isc_socketmgr_t *socketmgr,
		       dns_dispatchmgr_t *dispatchmgr,
		       isc_task_t *task, ns_interfacemgr_t **mgrp)
{
	isc_result_t result;
	ns_interfacemgr_t *mgr;

#ifndef USE_ROUTE_SOCKET
	UNUSED(task);
#endif

	REQUIRE(mctx != NULL);
	REQUIRE(mgrp != NULL);
	REQUIRE(*mgrp == NULL);

	mgr = isc_mem_get(mctx, sizeof(*mgr));
	if (mgr == NULL)
		return (ISC_R_NOMEMORY);

	mgr->mctx = NULL;
	isc_mem_attach(mctx, &mgr->mctx);

	result = isc_mutex_init(&mgr->lock);
	if (result != ISC_R_SUCCESS)
		goto cleanup_mem;

	mgr->taskmgr = taskmgr;
	mgr->socketmgr = socketmgr;
	mgr->dispatchmgr = dispatchmgr;
	mgr->generation = 1;
	mgr->listenon4 = NULL;
	mgr->listenon6 = NULL;

	ISC_LIST_INIT(mgr->interfaces);
	ISC_LIST_INIT(mgr->listenon);

	/*
	 * The listen-on lists are initially empty.
	 */
	result = ns_listenlist_create(mctx, &mgr->listenon4);
	if (result != ISC_R_SUCCESS)
		goto cleanup_mem;
	ns_listenlist_attach(mgr->listenon4, &mgr->listenon6);

	result = dns_aclenv_init(mctx, &mgr->aclenv);
	if (result != ISC_R_SUCCESS)
		goto cleanup_listenon;
#ifdef HAVE_GEOIP
	mgr->aclenv.geoip = ns_g_geoip;
#endif

#ifdef USE_ROUTE_SOCKET
	mgr->route = NULL;
	result = isc_socket_create(mgr->socketmgr, ROUTE_SOCKET_PROTOCOL,
				   isc_sockettype_raw, &mgr->route);
	switch (result) {
	case ISC_R_NOPERM:
	case ISC_R_SUCCESS:
	case ISC_R_NOTIMPLEMENTED:
	case ISC_R_FAMILYNOSUPPORT:
	    break;
	default:
		goto cleanup_aclenv;
	}

	mgr->task = NULL;
	if (mgr->route != NULL)
		isc_task_attach(task, &mgr->task);
	mgr->references = (mgr->route != NULL) ? 2 : 1;
#else
	mgr->references = 1;
#endif
	mgr->magic = IFMGR_MAGIC;
	*mgrp = mgr;

#ifdef USE_ROUTE_SOCKET
	if (mgr->route != NULL) {
		isc_region_t r = { mgr->buf, sizeof(mgr->buf) };

		result = isc_socket_recv(mgr->route, &r, 1, mgr->task,
					 route_event, mgr);
		if (result != ISC_R_SUCCESS) {
			isc_task_detach(&mgr->task);
			isc_socket_detach(&mgr->route);
			ns_interfacemgr_detach(&mgr);
		}
	}
#endif
	return (ISC_R_SUCCESS);

#ifdef USE_ROUTE_SOCKET
 cleanup_aclenv:
	dns_aclenv_destroy(&mgr->aclenv);
#endif
 cleanup_listenon:
	ns_listenlist_detach(&mgr->listenon4);
	ns_listenlist_detach(&mgr->listenon6);
 cleanup_mem:
	isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr));
	return (result);
}
Exemplo n.º 7
0
void isc_taskpool_gettask(isc_taskpool_t *pool, unsigned int hash,
			  isc_task_t **targetp)
{
	isc_task_attach(pool->tasks[hash % pool->ntasks], targetp);
}
Exemplo n.º 8
0
isc_result_t
dns_lookup_create(isc_mem_t *mctx, dns_name_t *name, dns_rdatatype_t type,
		  dns_view_t *view, unsigned int options, isc_task_t *task,
		  isc_taskaction_t action, void *arg, dns_lookup_t **lookupp)
{
	isc_result_t result;
	dns_lookup_t *lookup;
	isc_event_t *ievent;

	lookup = isc_mem_get(mctx, sizeof(*lookup));
	if (lookup == NULL)
		return (ISC_R_NOMEMORY);
	lookup->mctx = NULL;
	isc_mem_attach(mctx, &lookup->mctx);
	lookup->options = options;

	ievent = isc_event_allocate(mctx, lookup, DNS_EVENT_LOOKUPDONE,
				    action, arg, sizeof(*lookup->event));
	if (ievent == NULL) {
		result = ISC_R_NOMEMORY;
		goto cleanup_lookup;
	}
	lookup->event = (dns_lookupevent_t *)ievent;
	lookup->event->ev_destroy = levent_destroy;
	lookup->event->ev_destroy_arg = mctx;
	lookup->event->result = ISC_R_FAILURE;
	lookup->event->name = NULL;
	lookup->event->rdataset = NULL;
	lookup->event->sigrdataset = NULL;
	lookup->event->db = NULL;
	lookup->event->node = NULL;

	lookup->task = NULL;
	isc_task_attach(task, &lookup->task);

	result = isc_mutex_init(&lookup->lock);
	if (result != ISC_R_SUCCESS)
		goto cleanup_event;

	dns_fixedname_init(&lookup->name);

	result = dns_name_copy(name, dns_fixedname_name(&lookup->name), NULL);
	if (result != ISC_R_SUCCESS)
		goto cleanup_lock;

	lookup->type = type;
	lookup->view = NULL;
	dns_view_attach(view, &lookup->view);
	lookup->fetch = NULL;
	lookup->restarts = 0;
	lookup->canceled = ISC_FALSE;
	dns_rdataset_init(&lookup->rdataset);
	dns_rdataset_init(&lookup->sigrdataset);
	lookup->magic = LOOKUP_MAGIC;

	*lookupp = lookup;

	lookup_find(lookup, NULL);

	return (ISC_R_SUCCESS);

 cleanup_lock:
	DESTROYLOCK(&lookup->lock);

 cleanup_event:
	ievent = (isc_event_t *)lookup->event;
	isc_event_free(&ievent);
	lookup->event = NULL;

	isc_task_detach(&lookup->task);

 cleanup_lookup:
	isc_mem_putanddetach(&mctx, lookup, sizeof(*lookup));

	return (result);
}
Exemplo n.º 9
0
void
isc_taskpool_gettask(isc_taskpool_t *pool, isc_task_t **targetp) {
	isc_uint32_t i;
	isc_random_get(&i);
	isc_task_attach(pool->tasks[i % pool->ntasks], targetp);
}
Exemplo n.º 10
0
int
main(int argc, char *argv[]) {
	unsigned int workers;
	t_info *t1, *t2;
	isc_task_t *task;
	isc_mem_t *mctx, *mctx2;

	RUNTIME_CHECK(isc_app_start() == ISC_R_SUCCESS);

	if (argc > 1)
		workers = atoi(argv[1]);
	else
		workers = 2;
	printf("%d workers\n", workers);

	mctx = NULL;
	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
	mctx2 = NULL;
	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx2) == ISC_R_SUCCESS);
	RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &task_manager) ==
		      ISC_R_SUCCESS);
	RUNTIME_CHECK(isc_timermgr_create(mctx, &timer_manager) ==
		      ISC_R_SUCCESS);

	t1 = new_task(mctx, NULL);
	t2 = new_task(mctx2, NULL);
	isc_task_attach(t2->task, &t1->peer);
	isc_task_attach(t1->task, &t2->peer);

	/*
	 * Test run-triggered shutdown.
	 */
	(void)new_task(mctx2, "foo");

	/*
	 * Test implicit shutdown.
	 */
	task = NULL;
	RUNTIME_CHECK(isc_task_create(task_manager, 0, &task) ==
		      ISC_R_SUCCESS);
	isc_task_detach(&task);

	/*
	 * Test anti-zombie code.
	 */
	RUNTIME_CHECK(isc_task_create(task_manager, 0, &task) ==
		      ISC_R_SUCCESS);
	isc_task_detach(&task);

	RUNTIME_CHECK(isc_app_run() == ISC_R_SUCCESS);

	isc_taskmgr_destroy(&task_manager);
	isc_timermgr_destroy(&timer_manager);

	printf("Statistics for mctx:\n");
	isc_mem_stats(mctx, stdout);
	isc_mem_destroy(&mctx);
	printf("Statistics for mctx2:\n");
	isc_mem_stats(mctx2, stdout);
	isc_mem_destroy(&mctx2);

	isc_app_finish();

	return (0);
}