Exemplo n.º 1
0
/*
 * Initialize a semaphore.
 *
 * sem - allocated semaphore that will be initialized
 * value - number of times we can acquire the semaphore.
 */
isc_result_t
semaphore_init(semaphore_t *sem, int value)
{
	isc_result_t result;

	REQUIRE(sem != NULL);
	REQUIRE(value > 0);

	sem->value = value;
	result = isc_mutex_init(&sem->mutex);
	if (result != ISC_R_SUCCESS)
		return result;

	result = isc_condition_init(&sem->cond);
	if (result != ISC_R_SUCCESS)
		DESTROYLOCK(&sem->mutex);

	return result;
}
Exemplo n.º 2
0
Arquivo: task.c Projeto: OPSF/uClinux
isc_result_t
isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
		   unsigned int default_quantum, isc_taskmgr_t **managerp)
{
	isc_result_t result;
	unsigned int i, started = 0;
	isc_taskmgr_t *manager;

	/*
	 * Create a new task manager.
	 */

	REQUIRE(workers > 0);
	REQUIRE(managerp != NULL && *managerp == NULL);

#ifndef ISC_PLATFORM_USETHREADS
	UNUSED(i);
	UNUSED(started);
	UNUSED(workers);

	if (taskmgr != NULL) {
		taskmgr->refs++;
		*managerp = taskmgr;
		return (ISC_R_SUCCESS);
	}
#endif /* ISC_PLATFORM_USETHREADS */

	manager = isc_mem_get(mctx, sizeof(*manager));
	if (manager == NULL)
		return (ISC_R_NOMEMORY);
	manager->magic = TASK_MANAGER_MAGIC;
	manager->mctx = NULL;
	result = isc_mutex_init(&manager->lock);
	if (result != ISC_R_SUCCESS)
		goto cleanup_mgr;

#ifdef ISC_PLATFORM_USETHREADS
	manager->workers = 0;
	manager->threads = isc_mem_allocate(mctx,
					    workers * sizeof(isc_thread_t));
	if (manager->threads == NULL) {
		result = ISC_R_NOMEMORY;
		goto cleanup_lock;
	}
	if (isc_condition_init(&manager->work_available) != ISC_R_SUCCESS) {
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_condition_init() %s",
				 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
						ISC_MSG_FAILED, "failed"));
		result = ISC_R_UNEXPECTED;
		goto cleanup_threads;
	}
	if (isc_condition_init(&manager->exclusive_granted) != ISC_R_SUCCESS) {
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_condition_init() %s",
				 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
						ISC_MSG_FAILED, "failed"));
		result = ISC_R_UNEXPECTED;
		goto cleanup_workavailable;
	}
#endif /* ISC_PLATFORM_USETHREADS */
	if (default_quantum == 0)
		default_quantum = DEFAULT_DEFAULT_QUANTUM;
	manager->default_quantum = default_quantum;
	INIT_LIST(manager->tasks);
	INIT_LIST(manager->ready_tasks);
	manager->tasks_running = 0;
	manager->exclusive_requested = ISC_FALSE;
	manager->exiting = ISC_FALSE;

	isc_mem_attach(mctx, &manager->mctx);

#ifdef ISC_PLATFORM_USETHREADS
	LOCK(&manager->lock);
	/*
	 * Start workers.
	 */
	for (i = 0; i < workers; i++) {
		if (isc_thread_create(run, manager,
				      &manager->threads[manager->workers]) ==
		    ISC_R_SUCCESS) {
			manager->workers++;
			started++;
		}
	}
	UNLOCK(&manager->lock);

	if (started == 0) {
		manager_free(manager);
		return (ISC_R_NOTHREADS);
	}
	isc_thread_setconcurrency(workers);
#else /* ISC_PLATFORM_USETHREADS */
	manager->refs = 1;
	taskmgr = manager;
#endif /* ISC_PLATFORM_USETHREADS */

	*managerp = manager;

	return (ISC_R_SUCCESS);

#ifdef ISC_PLATFORM_USETHREADS
 cleanup_workavailable:
	(void)isc_condition_destroy(&manager->work_available);
 cleanup_threads:
	isc_mem_free(mctx, manager->threads);
 cleanup_lock:
	DESTROYLOCK(&manager->lock);
#endif
 cleanup_mgr:
	isc_mem_put(mctx, manager, sizeof(*manager));
	return (result);
}
Exemplo n.º 3
0
ISC_TIMERFUNC_SCOPE isc_result_t
isc__timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
	isc__timermgr_t *manager;
	isc_result_t result;

	/*
	 * Create a timer manager.
	 */

	REQUIRE(managerp != NULL && *managerp == NULL);

#ifdef USE_SHARED_MANAGER
	if (timermgr != NULL) {
		timermgr->refs++;
		*managerp = (isc_timermgr_t *)timermgr;
		return (ISC_R_SUCCESS);
	}
#endif /* USE_SHARED_MANAGER */

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

	manager->common.impmagic = TIMER_MANAGER_MAGIC;
	manager->common.magic = ISCAPI_TIMERMGR_MAGIC;
	manager->common.methods = (isc_timermgrmethods_t *)&timermgrmethods;
	manager->mctx = NULL;
	manager->done = ISC_FALSE;
	INIT_LIST(manager->timers);
	manager->nscheduled = 0;
	isc_time_settoepoch(&manager->due);
	manager->heap = NULL;
	result = isc_heap_create(mctx, sooner, set_index, 0, &manager->heap);
	if (result != ISC_R_SUCCESS) {
		INSIST(result == ISC_R_NOMEMORY);
		isc_mem_put(mctx, manager, sizeof(*manager));
		return (ISC_R_NOMEMORY);
	}
	result = isc_mutex_init(&manager->lock);
	if (result != ISC_R_SUCCESS) {
		isc_heap_destroy(&manager->heap);
		isc_mem_put(mctx, manager, sizeof(*manager));
		return (result);
	}
	isc_mem_attach(mctx, &manager->mctx);
#ifdef USE_TIMER_THREAD
	if (isc_condition_init(&manager->wakeup) != ISC_R_SUCCESS) {
		isc_mem_detach(&manager->mctx);
		DESTROYLOCK(&manager->lock);
		isc_heap_destroy(&manager->heap);
		isc_mem_put(mctx, manager, sizeof(*manager));
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_condition_init() %s",
				 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
						ISC_MSG_FAILED, "failed"));
		return (ISC_R_UNEXPECTED);
	}
	if (isc_thread_create(run, manager, &manager->thread) !=
	    ISC_R_SUCCESS) {
		isc_mem_detach(&manager->mctx);
		(void)isc_condition_destroy(&manager->wakeup);
		DESTROYLOCK(&manager->lock);
		isc_heap_destroy(&manager->heap);
		isc_mem_put(mctx, manager, sizeof(*manager));
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_thread_create() %s",
				 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
						ISC_MSG_FAILED, "failed"));
		return (ISC_R_UNEXPECTED);
	}
#endif
#ifdef USE_SHARED_MANAGER
	manager->refs = 1;
	timermgr = manager;
#endif /* USE_SHARED_MANAGER */

	*managerp = (isc_timermgr_t *)manager;

	return (ISC_R_SUCCESS);
}
Exemplo n.º 4
0
static int
t_timers5(void) {
	char		*p;
	int		result;
	isc_mem_t	*mctx;
	isc_taskmgr_t	*tmgr;
	unsigned int	workers;
	isc_result_t	isc_result;
	isc_timermgr_t	*timermgr;
	isc_event_t	*event;
	isc_time_t	expires;
	isc_interval_t	interval;

	T5_startflag = 0;
	T5_shutdownflag = 0;
	T5_eventcnt = 0;

	workers = 2;
	p = t_getenv("ISC_TASK_WORKERS");
	if (p != NULL)
		workers = atoi(p);

	mctx = NULL;
	isc_result = isc_mem_create(0, 0, &mctx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mem_create failed %s\n",
		       isc_result_totext(isc_result));
		return(T_UNRESOLVED);
	}

	isc_result = isc_mutex_init(&T5_mx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mutex_init failed %s\n",
		       isc_result_totext(isc_result));
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_condition_init(&T5_cv);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_condition_init failed %s\n",
		       isc_result_totext(isc_result));
		DESTROYLOCK(&T5_mx);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	tmgr = NULL;
	isc_result = isc_taskmgr_create(mctx, workers, 0, &tmgr);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_taskmgr_create failed %s\n",
		       isc_result_totext(isc_result));
		DESTROYLOCK(&T5_mx);
		(void) isc_condition_destroy(&T5_cv);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	timermgr = NULL;
	isc_result = isc_timermgr_create(mctx, &timermgr);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_timermgr_create failed %s\n",
		       isc_result_totext(isc_result));
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&T5_mx);
		(void) isc_condition_destroy(&T5_cv);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	T5_task1 = NULL;
	isc_result = isc_task_create(tmgr, 0, &T5_task1);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_task_create failed %s\n",
		       isc_result_totext(isc_result));
		isc_timermgr_destroy(&timermgr);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&T5_mx);
		(void) isc_condition_destroy(&T5_cv);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_task_onshutdown(T5_task1, t5_shutdown_event, NULL);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_task_onshutdown failed %s\n",
		       isc_result_totext(isc_result));
		isc_timermgr_destroy(&timermgr);
		isc_task_destroy(&T5_task1);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&T5_mx);
		(void) isc_condition_destroy(&T5_cv);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	T5_task2 = NULL;
	isc_result = isc_task_create(tmgr, 0, &T5_task2);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_task_create failed %s\n",
		       isc_result_totext(isc_result));
		isc_timermgr_destroy(&timermgr);
		isc_task_destroy(&T5_task1);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&T5_mx);
		(void) isc_condition_destroy(&T5_cv);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_mutex_lock(&T5_mx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mutex_lock failed %s\n",
		       isc_result_totext(isc_result));
		isc_timermgr_destroy(&timermgr);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&T5_mx);
		(void) isc_condition_destroy(&T5_cv);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	event = isc_event_allocate(mctx, (void *)1 , (isc_eventtype_t)1,
				   t5_start_event, NULL, sizeof(*event));
	isc_task_send(T5_task1, &event);

	isc_time_settoepoch(&expires);
	isc_interval_set(&interval, T5_SECONDS, 0);

	T5_tickertimer = NULL;
	isc_result = isc_timer_create(timermgr, isc_timertype_ticker,
				      &expires, &interval, T5_task1,
				      t5_tick_event, NULL, &T5_tickertimer);

	if (isc_result != ISC_R_SUCCESS) {
		isc_timermgr_destroy(&timermgr);
		(void) isc_condition_signal(&T5_cv);
		(void) isc_mutex_unlock(&T5_mx);
		isc_task_destroy(&T5_task1);
		isc_task_destroy(&T5_task2);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&T5_mx);
		(void) isc_condition_destroy(&T5_cv);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	T5_oncetimer = NULL;
	isc_interval_set(&interval, (T5_SECONDS * T5_NTICKS) + 2, 0);
	isc_result = isc_time_nowplusinterval(&expires, &interval);
	if (isc_result != ISC_R_SUCCESS) {
		isc_timer_detach(&T5_tickertimer);
		isc_timermgr_destroy(&timermgr);
		(void)isc_condition_signal(&T5_cv);
		(void)isc_mutex_unlock(&T5_mx);
		isc_task_destroy(&T5_task1);
		isc_task_destroy(&T5_task2);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&T5_mx);
		(void) isc_condition_destroy(&T5_cv);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_interval_set(&interval, 0, 0);
	isc_result = isc_timer_create(timermgr, isc_timertype_once,
				      &expires, &interval, T5_task2,
				      t5_once_event, NULL, &T5_oncetimer);

	if (isc_result != ISC_R_SUCCESS) {
		isc_timer_detach(&T5_tickertimer);
		isc_timermgr_destroy(&timermgr);
		(void) isc_condition_signal(&T5_cv);
		(void) isc_mutex_unlock(&T5_mx);
		isc_task_destroy(&T5_task1);
		isc_task_destroy(&T5_task2);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&T5_mx);
		(void) isc_condition_destroy(&T5_cv);
		isc_mem_destroy(&mctx);
		++T5_nprobs;
		return(T_UNRESOLVED);
	}

	/*
	 * Wait for shutdown processing to complete.
	 */
	while (! T5_shutdownflag) {
		isc_result = isc_condition_wait(&T5_cv, &T5_mx);
		if (isc_result != ISC_R_SUCCESS) {
			t_info("isc_condition_waituntil failed %s\n",
			       isc_result_totext(isc_result));
			++T5_nprobs;
		}
	}

	isc_result = isc_mutex_unlock(&T5_mx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mutex_unlock failed %s\n",
		       isc_result_totext(isc_result));
		++T5_nprobs;
	}

	if (T5_eventcnt != 1) {
		t_info("processed %d events\n", T5_eventcnt);
		++T5_nfails;
	}

	isc_timer_detach(&T5_tickertimer);
	isc_timer_detach(&T5_oncetimer);
	isc_timermgr_destroy(&timermgr);
	isc_task_destroy(&T5_task1);
	isc_task_destroy(&T5_task2);
	isc_taskmgr_destroy(&tmgr);
	DESTROYLOCK(&T5_mx);
	(void) isc_condition_destroy(&T5_cv);
	isc_mem_destroy(&mctx);

	result = T_UNRESOLVED;

	if ((T5_nfails == 0) && (T5_nprobs == 0))
		result = T_PASS;
	else if (T5_nfails)
		result = T_FAIL;

	return (result);
}
Exemplo n.º 5
0
static void
t_timers_x(isc_timertype_t timertype, isc_time_t *expires,
	   isc_interval_t *interval,
	   void (*action)(isc_task_t *, isc_event_t *))
{
	char		*p;
	isc_mem_t	*mctx;
	isc_taskmgr_t	*tmgr;
	isc_task_t	*task;
	unsigned int	workers;
	isc_result_t	isc_result;
	isc_timermgr_t	*timermgr;

	Tx_eventcnt = 0;
	isc_time_settoepoch(&Tx_endtime);

	workers = 2;
	p = t_getenv("ISC_TASK_WORKERS");
	if (p != NULL)
		workers = atoi(p);

	mctx = NULL;
	isc_result = isc_mem_create(0, 0, &mctx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mem_create failed %s\n",
		       isc_result_totext(isc_result));
		++Tx_nprobs;
		return;
	}

	isc_result = isc_mutex_init(&Tx_mx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mutex_init failed %s\n",
		       isc_result_totext(isc_result));
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	isc_result = isc_condition_init(&Tx_cv);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_condition_init failed %s\n",
		       isc_result_totext(isc_result));
		DESTROYLOCK(&Tx_mx);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	tmgr = NULL;
	isc_result = isc_taskmgr_create(mctx, workers, 0, &tmgr);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_taskmgr_create failed %s\n",
		       isc_result_totext(isc_result));
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	timermgr = NULL;
	isc_result = isc_timermgr_create(mctx, &timermgr);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_timermgr_create failed %s\n",
		       isc_result_totext(isc_result));
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	isc_result = isc_mutex_lock(&Tx_mx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mutex_lock failed %s\n",
		       isc_result_totext(isc_result));
		isc_timermgr_destroy(&timermgr);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	task = NULL;
	isc_result = isc_task_create(tmgr, 0, &task);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_task_create failed %s\n",
		       isc_result_totext(isc_result));
		isc_timermgr_destroy(&timermgr);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	isc_result = isc_task_onshutdown(task, tx_sde, NULL);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_task_onshutdown failed %s\n",
		       isc_result_totext(isc_result));
		isc_timermgr_destroy(&timermgr);
		isc_task_destroy(&task);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	isc_result = isc_time_now(&Tx_lasttime);
	if (isc_result != ISC_R_SUCCESS) {
		isc_timermgr_destroy(&timermgr);
		isc_task_destroy(&task);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	Tx_timer = NULL;
	isc_result = isc_timer_create(timermgr, timertype, expires, interval,
				      task, action, (void *)timertype,
				      &Tx_timer);

	if (isc_result != ISC_R_SUCCESS) {
		isc_timermgr_destroy(&timermgr);
		isc_task_destroy(&task);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	/*
	 * Wait for shutdown processing to complete.
	 */
	while (Tx_eventcnt != Tx_nevents) {
		isc_result = isc_condition_wait(&Tx_cv, &Tx_mx);
		if (isc_result != ISC_R_SUCCESS) {
			t_info("isc_condition_waituntil failed %s\n",
			       isc_result_totext(isc_result));
			++Tx_nprobs;
		}
	}

	isc_result = isc_mutex_unlock(&Tx_mx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mutex_unlock failed %s\n",
		       isc_result_totext(isc_result));
		++Tx_nprobs;
	}

	isc_task_detach(&task);
	isc_taskmgr_destroy(&tmgr);
	isc_timermgr_destroy(&timermgr);
	DESTROYLOCK(&Tx_mx);
	(void) isc_condition_destroy(&Tx_cv);
	isc_mem_destroy(&mctx);

}
Exemplo n.º 6
0
isc_result_t
isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
		unsigned int write_quota)
{
	isc_result_t result;

	REQUIRE(rwl != NULL);

	/*
	 * In case there's trouble initializing, we zero magic now.  If all
	 * goes well, we'll set it to RWLOCK_MAGIC.
	 */
	rwl->magic = 0;

	rwl->spins = 0;
#if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
	rwl->write_requests = 0;
	rwl->write_completions = 0;
	rwl->cnt_and_flag = 0;
	rwl->readers_waiting = 0;
	rwl->write_granted = 0;
	if (read_quota != 0) {
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "read quota is not supported");
	}
	if (write_quota == 0)
		write_quota = RWLOCK_DEFAULT_WRITE_QUOTA;
	rwl->write_quota = write_quota;
#else
	rwl->type = isc_rwlocktype_read;
	rwl->original = isc_rwlocktype_none;
	rwl->active = 0;
	rwl->granted = 0;
	rwl->readers_waiting = 0;
	rwl->writers_waiting = 0;
	if (read_quota == 0)
		read_quota = RWLOCK_DEFAULT_READ_QUOTA;
	rwl->read_quota = read_quota;
	if (write_quota == 0)
		write_quota = RWLOCK_DEFAULT_WRITE_QUOTA;
	rwl->write_quota = write_quota;
#endif

	result = isc_mutex_init(&rwl->lock);
	if (result != ISC_R_SUCCESS)
		return (result);

	result = isc_condition_init(&rwl->readable);
	if (result != ISC_R_SUCCESS) {
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_condition_init(readable) %s: %s",
				 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
						ISC_MSG_FAILED, "failed"),
				 isc_result_totext(result));
		result = ISC_R_UNEXPECTED;
		goto destroy_lock;
	}
	result = isc_condition_init(&rwl->writeable);
	if (result != ISC_R_SUCCESS) {
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_condition_init(writeable) %s: %s",
				 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
						ISC_MSG_FAILED, "failed"),
				 isc_result_totext(result));
		result = ISC_R_UNEXPECTED;
		goto destroy_rcond;
	}

	rwl->magic = RWLOCK_MAGIC;

	return (ISC_R_SUCCESS);

  destroy_rcond:
	(void)isc_condition_destroy(&rwl->readable);
  destroy_lock:
	DESTROYLOCK(&rwl->lock);

	return (result);
}
Exemplo n.º 7
0
Arquivo: app.c Projeto: execunix/vinos
isc_result_t
isc__app_ctxstart(isc_appctx_t *ctx0) {
	isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
	isc_result_t result;
	int presult;
	sigset_t sset;
	char strbuf[ISC_STRERRORSIZE];

	REQUIRE(VALID_APPCTX(ctx));

	/*
	 * Start an ISC library application.
	 */

#ifdef NEED_PTHREAD_INIT
	/*
	 * BSDI 3.1 seg faults in pthread_sigmask() if we don't do this.
	 */
	presult = pthread_init();
	if (presult != 0) {
		isc__strerror(presult, strbuf, sizeof(strbuf));
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_app_start() pthread_init: %s", strbuf);
		return (ISC_R_UNEXPECTED);
	}
#endif

#ifdef ISC_PLATFORM_USETHREADS
#ifdef HAVE_LINUXTHREADS
	main_thread = pthread_self();
#endif /* HAVE_LINUXTHREADS */

	result = isc_mutex_init(&ctx->readylock);
	if (result != ISC_R_SUCCESS)
		return (result);

	result = isc_condition_init(&ctx->ready);
	if (result != ISC_R_SUCCESS)
		goto cleanup_rlock;

	result = isc_mutex_init(&ctx->lock);
	if (result != ISC_R_SUCCESS)
		goto cleanup_rcond;
#else /* ISC_PLATFORM_USETHREADS */
	result = isc_mutex_init(&ctx->lock);
	if (result != ISC_R_SUCCESS)
		goto cleanup;
#endif /* ISC_PLATFORM_USETHREADS */

	ISC_LIST_INIT(ctx->on_run);

	ctx->shutdown_requested = ISC_FALSE;
	ctx->running = ISC_FALSE;
	ctx->want_shutdown = ISC_FALSE;
	ctx->want_reload = ISC_FALSE;
	ctx->blocked = ISC_FALSE;

#ifndef HAVE_SIGWAIT
	/*
	 * Install do-nothing handlers for SIGINT and SIGTERM.
	 *
	 * We install them now because BSDI 3.1 won't block
	 * the default actions, regardless of what we do with
	 * pthread_sigmask().
	 */
	result = handle_signal(SIGINT, exit_action);
	if (result != ISC_R_SUCCESS)
		goto cleanup;
	result = handle_signal(SIGTERM, exit_action);
	if (result != ISC_R_SUCCESS)
		goto cleanup;
#endif

	/*
	 * Always ignore SIGPIPE.
	 */
	result = handle_signal(SIGPIPE, SIG_IGN);
	if (result != ISC_R_SUCCESS)
		goto cleanup;

	/*
	 * On Solaris 2, delivery of a signal whose action is SIG_IGN
	 * will not cause sigwait() to return. We may have inherited
	 * unexpected actions for SIGHUP, SIGINT, and SIGTERM from our parent
	 * process (e.g, Solaris cron).  Set an action of SIG_DFL to make
	 * sure sigwait() works as expected.  Only do this for SIGTERM and
	 * SIGINT if we don't have sigwait(), since a different handler is
	 * installed above.
	 */
	result = handle_signal(SIGHUP, SIG_DFL);
	if (result != ISC_R_SUCCESS)
		goto cleanup;

#ifdef HAVE_SIGWAIT
	result = handle_signal(SIGTERM, SIG_DFL);
	if (result != ISC_R_SUCCESS)
		goto cleanup;
	result = handle_signal(SIGINT, SIG_DFL);
	if (result != ISC_R_SUCCESS)
		goto cleanup;
#endif

#ifdef ISC_PLATFORM_USETHREADS
	if (isc_bind9) {
	/*
	 * Block SIGHUP, SIGINT, SIGTERM.
	 *
	 * If isc_app_start() is called from the main thread before any other
	 * threads have been created, then the pthread_sigmask() call below
	 * will result in all threads having SIGHUP, SIGINT and SIGTERM
	 * blocked by default, ensuring that only the thread that calls
	 * sigwait() for them will get those signals.
	 */
	if (sigemptyset(&sset) != 0 ||
	    sigaddset(&sset, SIGHUP) != 0 ||
	    sigaddset(&sset, SIGINT) != 0 ||
	    sigaddset(&sset, SIGTERM) != 0) {
		isc__strerror(errno, strbuf, sizeof(strbuf));
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_app_start() sigsetops: %s", strbuf);
		result = ISC_R_UNEXPECTED;
		goto cleanup;
	}
	presult = pthread_sigmask(SIG_BLOCK, &sset, NULL);
	if (presult != 0) {
		isc__strerror(presult, strbuf, sizeof(strbuf));
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_app_start() pthread_sigmask: %s",
				 strbuf);
		result = ISC_R_UNEXPECTED;
		goto cleanup;
	}
	}
#else /* ISC_PLATFORM_USETHREADS */
	/*
	 * Unblock SIGHUP, SIGINT, SIGTERM.
	 *
	 * If we're not using threads, we need to make sure that SIGHUP,
	 * SIGINT and SIGTERM are not inherited as blocked from the parent
	 * process.
	 */
	if (sigemptyset(&sset) != 0 ||
	    sigaddset(&sset, SIGHUP) != 0 ||
	    sigaddset(&sset, SIGINT) != 0 ||
	    sigaddset(&sset, SIGTERM) != 0) {
		isc__strerror(errno, strbuf, sizeof(strbuf));
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_app_start() sigsetops: %s", strbuf);
		result = ISC_R_UNEXPECTED;
		goto cleanup;
	}
	presult = sigprocmask(SIG_UNBLOCK, &sset, NULL);
	if (presult != 0) {
		isc__strerror(errno, strbuf, sizeof(strbuf));
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_app_start() sigprocmask: %s", strbuf);
		result = ISC_R_UNEXPECTED;
		goto cleanup;
	}
#endif /* ISC_PLATFORM_USETHREADS */

	return (ISC_R_SUCCESS);

 cleanup:
#ifdef ISC_PLATFORM_USETHREADS
 cleanup_rcond:
	(void)isc_condition_destroy(&ctx->ready);

 cleanup_rlock:
	(void)isc_mutex_destroy(&ctx->readylock);
#endif /* ISC_PLATFORM_USETHREADS */
	return (result);
}