⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 task.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 3 页
字号:
	 * Send '*event' to '*taskp' and then detach '*taskp' from its	 * task.	 */	REQUIRE(taskp != NULL);	task = *taskp;	REQUIRE(VALID_TASK(task));	XTRACE("isc_task_sendanddetach");	LOCK(&task->lock);	idle1 = task_send(task, eventp);	idle2 = task_detach(task);	UNLOCK(&task->lock);	/*	 * If idle1, then idle2 shouldn't be true as well since we're holding	 * the task lock, and thus the task cannot switch from ready back to	 * idle.	 */	INSIST(!(idle1 && idle2));	if (idle1 || idle2)		task_ready(task);	*taskp = NULL;}#define PURGE_OK(event)	(((event)->ev_attributes & ISC_EVENTATTR_NOPURGE) == 0)static unsigned intdequeue_events(isc_task_t *task, void *sender, isc_eventtype_t first,	       isc_eventtype_t last, void *tag,	       isc_eventlist_t *events, isc_boolean_t purging){	isc_event_t *event, *next_event;	unsigned int count = 0;	REQUIRE(VALID_TASK(task));	REQUIRE(last >= first);	XTRACE("dequeue_events");	/*	 * Events matching 'sender', whose type is >= first and <= last, and	 * whose tag is 'tag' will be dequeued.  If 'purging', matching events	 * which are marked as unpurgable will not be dequeued.	 *	 * sender == NULL means "any sender", and tag == NULL means "any tag".	 */	LOCK(&task->lock);	for (event = HEAD(task->events); event != NULL; event = next_event) {		next_event = NEXT(event, ev_link);		if (event->ev_type >= first && event->ev_type <= last &&		    (sender == NULL || event->ev_sender == sender) &&		    (tag == NULL || event->ev_tag == tag) &&		    (!purging || PURGE_OK(event))) {			DEQUEUE(task->events, event, ev_link);			ENQUEUE(*events, event, ev_link);			count++;		}	}	UNLOCK(&task->lock);	return (count);}unsigned intisc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first,		    isc_eventtype_t last, void *tag){	unsigned int count;	isc_eventlist_t events;	isc_event_t *event, *next_event;	/*	 * Purge events from a task's event queue.	 */	XTRACE("isc_task_purgerange");	ISC_LIST_INIT(events);	count = dequeue_events(task, sender, first, last, tag, &events,			       ISC_TRUE);	for (event = HEAD(events); event != NULL; event = next_event) {		next_event = NEXT(event, ev_link);		isc_event_free(&event);	}	/*	 * Note that purging never changes the state of the task.	 */	return (count);}unsigned intisc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type,	       void *tag){	/*	 * Purge events from a task's event queue.	 */	XTRACE("isc_task_purge");	return (isc_task_purgerange(task, sender, type, type, tag));}isc_boolean_tisc_task_purgeevent(isc_task_t *task, isc_event_t *event) {	isc_event_t *curr_event, *next_event;	/*	 * Purge 'event' from a task's event queue.	 *	 * XXXRTH:  WARNING:  This method may be removed before beta.	 */	REQUIRE(VALID_TASK(task));	/*	 * If 'event' is on the task's event queue, it will be purged,	 * unless it is marked as unpurgeable.  'event' does not have to be	 * on the task's event queue; in fact, it can even be an invalid	 * pointer.  Purging only occurs if the event is actually on the task's	 * event queue.	 *	 * Purging never changes the state of the task.	 */	LOCK(&task->lock);	for (curr_event = HEAD(task->events);	     curr_event != NULL;	     curr_event = next_event) {		next_event = NEXT(curr_event, ev_link);		if (curr_event == event && PURGE_OK(event)) {			DEQUEUE(task->events, curr_event, ev_link);			break;		}	}	UNLOCK(&task->lock);	if (curr_event == NULL)		return (ISC_FALSE);	isc_event_free(&curr_event);	return (ISC_TRUE);}unsigned intisc_task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first,		     isc_eventtype_t last, void *tag,		     isc_eventlist_t *events){	/*	 * Remove events from a task's event queue.	 */	XTRACE("isc_task_unsendrange");	return (dequeue_events(task, sender, first, last, tag, events,			       ISC_FALSE));}unsigned intisc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,		void *tag, isc_eventlist_t *events){	/*	 * Remove events from a task's event queue.	 */	XTRACE("isc_task_unsend");	return (dequeue_events(task, sender, type, type, tag, events,			       ISC_FALSE));}isc_result_tisc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, const void *arg){	isc_boolean_t disallowed = ISC_FALSE;	isc_result_t result = ISC_R_SUCCESS;	isc_event_t *event;	/*	 * Send a shutdown event with action 'action' and argument 'arg' when	 * 'task' is shutdown.	 */	REQUIRE(VALID_TASK(task));	REQUIRE(action != NULL);	event = isc_event_allocate(task->manager->mctx,				   NULL,				   ISC_TASKEVENT_SHUTDOWN,				   action,				   arg,				   sizeof(*event));	if (event == NULL)		return (ISC_R_NOMEMORY);	LOCK(&task->lock);	if (TASK_SHUTTINGDOWN(task)) {		disallowed = ISC_TRUE;		result = ISC_R_SHUTTINGDOWN;	} else		ENQUEUE(task->on_shutdown, event, ev_link);	UNLOCK(&task->lock);	if (disallowed)		isc_mem_put(task->manager->mctx, event, sizeof(*event));	return (result);}voidisc_task_shutdown(isc_task_t *task) {	isc_boolean_t was_idle;	/*	 * Shutdown 'task'.	 */	REQUIRE(VALID_TASK(task));	LOCK(&task->lock);	was_idle = task_shutdown(task);	UNLOCK(&task->lock);	if (was_idle)		task_ready(task);}voidisc_task_destroy(isc_task_t **taskp) {	/*	 * Destroy '*taskp'.	 */	REQUIRE(taskp != NULL);	isc_task_shutdown(*taskp);	isc_task_detach(taskp);}voidisc_task_setname(isc_task_t *task, const char *name, void *tag) {	/*	 * Name 'task'.	 */	REQUIRE(VALID_TASK(task));#ifdef ISC_TASK_NAMES	LOCK(&task->lock);	memset(task->name, 0, sizeof(task->name));	strncpy(task->name, name, sizeof(task->name) - 1);	task->tag = tag;	UNLOCK(&task->lock);#else	UNUSED(name);	UNUSED(tag);#endif}const char *isc_task_getname(isc_task_t *task) {	return (task->name);}void *isc_task_gettag(isc_task_t *task) {	return (task->tag);}voidisc_task_getcurrenttime(isc_task_t *task, isc_stdtime_t *t) {	REQUIRE(VALID_TASK(task));	REQUIRE(t != NULL);	LOCK(&task->lock);	*t = task->now;	UNLOCK(&task->lock);}/*** *** Task Manager. ***/static voiddispatch(isc_taskmgr_t *manager) {	isc_task_t *task;#ifndef ISC_PLATFORM_USETHREADS	unsigned int total_dispatch_count = 0;	isc_tasklist_t ready_tasks;#endif /* ISC_PLATFORM_USETHREADS */	REQUIRE(VALID_MANAGER(manager));	/*	 * Again we're trying to hold the lock for as short a time as possible	 * and to do as little locking and unlocking as possible.	 *	 * In both while loops, the appropriate lock must be held before the	 * while body starts.  Code which acquired the lock at the top of	 * the loop would be more readable, but would result in a lot of	 * extra locking.  Compare:	 *	 * Straightforward:	 *	 *	LOCK();	 *	...	 *	UNLOCK();	 *	while (expression) {	 *		LOCK();	 *		...	 *		UNLOCK();	 *	 *	       	Unlocked part here...	 *	 *		LOCK();	 *		...	 *		UNLOCK();	 *	}	 *	 * Note how if the loop continues we unlock and then immediately lock.	 * For N iterations of the loop, this code does 2N+1 locks and 2N+1	 * unlocks.  Also note that the lock is not held when the while	 * condition is tested, which may or may not be important, depending	 * on the expression.	 *	 * As written:	 *	 *	LOCK();	 *	while (expression) {	 *		...	 *		UNLOCK();	 *	 *	       	Unlocked part here...	 *	 *		LOCK();	 *		...	 *	}	 *	UNLOCK();	 *	 * For N iterations of the loop, this code does N+1 locks and N+1	 * unlocks.  The while expression is always protected by the lock.	 */#ifndef ISC_PLATFORM_USETHREADS	ISC_LIST_INIT(ready_tasks);#endif	LOCK(&manager->lock);	while (!FINISHED(manager)) {#ifdef ISC_PLATFORM_USETHREADS		/*		 * For reasons similar to those given in the comment in		 * isc_task_send() above, it is safe for us to dequeue		 * the task while only holding the manager lock, and then		 * change the task to running state while only holding the		 * task lock.		 */		while ((EMPTY(manager->ready_tasks) ||		        manager->exclusive_requested) &&		  	!FINISHED(manager)) 	  	{			XTHREADTRACE(isc_msgcat_get(isc_msgcat,						    ISC_MSGSET_GENERAL,						    ISC_MSG_WAIT, "wait"));			WAIT(&manager->work_available, &manager->lock);			XTHREADTRACE(isc_msgcat_get(isc_msgcat,						    ISC_MSGSET_TASK,						    ISC_MSG_AWAKE, "awake"));		}#else /* ISC_PLATFORM_USETHREADS */		if (total_dispatch_count >= DEFAULT_TASKMGR_QUANTUM ||		    EMPTY(manager->ready_tasks))			break;#endif /* ISC_PLATFORM_USETHREADS */		XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TASK,					    ISC_MSG_WORKING, "working"));		task = HEAD(manager->ready_tasks);		if (task != NULL) {			unsigned int dispatch_count = 0;			isc_boolean_t done = ISC_FALSE;			isc_boolean_t requeue = ISC_FALSE;			isc_boolean_t finished = ISC_FALSE;			isc_event_t *event;			INSIST(VALID_TASK(task));			/*			 * Note we only unlock the manager lock if we actually			 * have a task to do.  We must reacquire the manager			 * lock before exiting the 'if (task != NULL)' block.			 */			DEQUEUE(manager->ready_tasks, task, ready_link);			manager->tasks_running++;			UNLOCK(&manager->lock);			LOCK(&task->lock);			INSIST(task->state == task_state_ready);			task->state = task_state_running;			XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,					      ISC_MSG_RUNNING, "running"));			isc_stdtime_get(&task->now);			do {				if (!EMPTY(task->events)) {					event = HEAD(task->events);					DEQUEUE(task->events, event, ev_link);					/*					 * Execute the event action.					 */					XTRACE(isc_msgcat_get(isc_msgcat,							    ISC_MSGSET_TASK,							    ISC_MSG_EXECUTE,							    "execute action"));					if (event->ev_action != NULL) {						UNLOCK(&task->lock);						(event->ev_action)(task,event);						LOCK(&task->lock);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -