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

📄 task.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003  Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. *//* $Id: task.c,v 1.85.2.3.8.4 2004/03/08 21:06:29 marka Exp $ *//* * Principal Author: Bob Halley *//* * XXXRTH  Need to document the states a task can be in, and the rules * for changing states. */#include <config.h>#include <isc/condition.h>#include <isc/event.h>#include <isc/magic.h>#include <isc/mem.h>#include <isc/msgs.h>#include <isc/platform.h>#include <isc/string.h>#include <isc/task.h>#include <isc/thread.h>#include <isc/util.h>#ifndef ISC_PLATFORM_USETHREADS#include "task_p.h"#endif /* ISC_PLATFORM_USETHREADS */#define ISC_TASK_NAMES 1#ifdef ISC_TASK_TRACE#define XTRACE(m)		fprintf(stderr, "task %p thread %lu: %s\n", \				       task, isc_thread_self(), (m))#define XTTRACE(t, m)		fprintf(stderr, "task %p thread %lu: %s\n", \				       (t), isc_thread_self(), (m))#define XTHREADTRACE(m)		fprintf(stderr, "thread %lu: %s\n", \				       isc_thread_self(), (m))#else#define XTRACE(m)#define XTTRACE(t, m)#define XTHREADTRACE(m)#endif/*** *** Types. ***/typedef enum {	task_state_idle, task_state_ready, task_state_running,	task_state_done} task_state_t;#define TASK_MAGIC			ISC_MAGIC('T', 'A', 'S', 'K')#define VALID_TASK(t)			ISC_MAGIC_VALID(t, TASK_MAGIC)struct isc_task {	/* Not locked. */	unsigned int			magic;	isc_taskmgr_t *			manager;	isc_mutex_t			lock;	/* Locked by task lock. */	task_state_t			state;	unsigned int			references;	isc_eventlist_t			events;	isc_eventlist_t			on_shutdown;	unsigned int			quantum;	unsigned int			flags;	isc_stdtime_t			now;#ifdef ISC_TASK_NAMES	char				name[16];	void *				tag;#endif	/* Locked by task manager lock. */	LINK(isc_task_t)		link;	LINK(isc_task_t)		ready_link;};#define TASK_F_SHUTTINGDOWN		0x01#define TASK_SHUTTINGDOWN(t)		(((t)->flags & TASK_F_SHUTTINGDOWN) \					 != 0)#define TASK_MANAGER_MAGIC		ISC_MAGIC('T', 'S', 'K', 'M')#define VALID_MANAGER(m)		ISC_MAGIC_VALID(m, TASK_MANAGER_MAGIC)struct isc_taskmgr {	/* Not locked. */	unsigned int			magic;	isc_mem_t *			mctx;	isc_mutex_t			lock;	unsigned int			workers;#ifdef ISC_PLATFORM_USETHREADS	isc_thread_t *			threads;#endif /* ISC_PLATFORM_USETHREADS */	/* Locked by task manager lock. */	unsigned int			default_quantum;	LIST(isc_task_t)		tasks;	isc_tasklist_t			ready_tasks;#ifdef ISC_PLATFORM_USETHREADS	isc_condition_t			work_available;	isc_condition_t			exclusive_granted;#endif /* ISC_PLATFORM_USETHREADS */	unsigned int			tasks_running;	isc_boolean_t			exclusive_requested;	isc_boolean_t			exiting;#ifndef ISC_PLATFORM_USETHREADS	unsigned int			refs;#endif /* ISC_PLATFORM_USETHREADS */};#define DEFAULT_TASKMGR_QUANTUM		10#define DEFAULT_DEFAULT_QUANTUM		5#define FINISHED(m)			((m)->exiting && EMPTY((m)->tasks))#ifndef ISC_PLATFORM_USETHREADSstatic isc_taskmgr_t *taskmgr = NULL;#endif /* ISC_PLATFORM_USETHREADS *//*** *** Tasks. ***/static voidtask_finished(isc_task_t *task) {	isc_taskmgr_t *manager = task->manager;	REQUIRE(EMPTY(task->events));	REQUIRE(EMPTY(task->on_shutdown));	REQUIRE(task->references == 0);	REQUIRE(task->state == task_state_done);	XTRACE("task_finished");	LOCK(&manager->lock);	UNLINK(manager->tasks, task, link);#ifdef ISC_PLATFORM_USETHREADS	if (FINISHED(manager)) {		/*		 * All tasks have completed and the		 * task manager is exiting.  Wake up		 * any idle worker threads so they		 * can exit.		 */		BROADCAST(&manager->work_available);	}#endif /* ISC_PLATFORM_USETHREADS */	UNLOCK(&manager->lock);	DESTROYLOCK(&task->lock);	task->magic = 0;	isc_mem_put(manager->mctx, task, sizeof(*task));}isc_result_tisc_task_create(isc_taskmgr_t *manager, unsigned int quantum,		isc_task_t **taskp){	isc_task_t *task;	isc_boolean_t exiting;	REQUIRE(VALID_MANAGER(manager));	REQUIRE(taskp != NULL && *taskp == NULL);	task = isc_mem_get(manager->mctx, sizeof(*task));	if (task == NULL)		return (ISC_R_NOMEMORY);	XTRACE("isc_task_create");	task->manager = manager;	if (isc_mutex_init(&task->lock) != ISC_R_SUCCESS) {		isc_mem_put(manager->mctx, task, sizeof(*task));		UNEXPECTED_ERROR(__FILE__, __LINE__,				 "isc_mutex_init() %s",				 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,						ISC_MSG_FAILED, "failed"));		return (ISC_R_UNEXPECTED);	}	task->state = task_state_idle;	task->references = 1;	INIT_LIST(task->events);	INIT_LIST(task->on_shutdown);	task->quantum = quantum;	task->flags = 0;	task->now = 0;#ifdef ISC_TASK_NAMES	memset(task->name, 0, sizeof(task->name));	task->tag = NULL;#endif	INIT_LINK(task, link);	INIT_LINK(task, ready_link);	exiting = ISC_FALSE;	LOCK(&manager->lock);	if (!manager->exiting) {		if (task->quantum == 0)			task->quantum = manager->default_quantum;		APPEND(manager->tasks, task, link);	} else		exiting = ISC_TRUE;	UNLOCK(&manager->lock);	if (exiting) {		DESTROYLOCK(&task->lock);		isc_mem_put(manager->mctx, task, sizeof(*task));		return (ISC_R_SHUTTINGDOWN);	}	task->magic = TASK_MAGIC;	*taskp = task;	return (ISC_R_SUCCESS);}voidisc_task_attach(isc_task_t *source, isc_task_t **targetp) {	/*	 * Attach *targetp to source.	 */	REQUIRE(VALID_TASK(source));	REQUIRE(targetp != NULL && *targetp == NULL);	XTTRACE(source, "isc_task_attach");	LOCK(&source->lock);	source->references++;	UNLOCK(&source->lock);	*targetp = source;}static inline isc_boolean_ttask_shutdown(isc_task_t *task) {	isc_boolean_t was_idle = ISC_FALSE;	isc_event_t *event, *prev;	/*	 * Caller must be holding the task's lock.	 */	XTRACE("task_shutdown");	if (! TASK_SHUTTINGDOWN(task)) {		XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,				      ISC_MSG_SHUTTINGDOWN, "shutting down"));		task->flags |= TASK_F_SHUTTINGDOWN;		if (task->state == task_state_idle) {			INSIST(EMPTY(task->events));			task->state = task_state_ready;			was_idle = ISC_TRUE;		}		INSIST(task->state == task_state_ready ||		       task->state == task_state_running);		/*		 * Note that we post shutdown events LIFO.		 */		for (event = TAIL(task->on_shutdown);		     event != NULL;		     event = prev) {			prev = PREV(event, ev_link);			DEQUEUE(task->on_shutdown, event, ev_link);			ENQUEUE(task->events, event, ev_link);		}	}	return (was_idle);}static inline voidtask_ready(isc_task_t *task) {	isc_taskmgr_t *manager = task->manager;	REQUIRE(VALID_MANAGER(manager));	REQUIRE(task->state == task_state_ready);	XTRACE("task_ready");	LOCK(&manager->lock);	ENQUEUE(manager->ready_tasks, task, ready_link);#ifdef ISC_PLATFORM_USETHREADS	SIGNAL(&manager->work_available);#endif /* ISC_PLATFORM_USETHREADS */	UNLOCK(&manager->lock);}static inline isc_boolean_ttask_detach(isc_task_t *task) {	/*	 * Caller must be holding the task lock.	 */	REQUIRE(task->references > 0);	XTRACE("detach");	task->references--;	if (task->references == 0 && task->state == task_state_idle) {		INSIST(EMPTY(task->events));		/*		 * There are no references to this task, and no		 * pending events.  We could try to optimize and		 * either initiate shutdown or clean up the task,		 * depending on its state, but it's easier to just		 * make the task ready and allow run() or the event		 * loop to deal with shutting down and termination.		 */		task->state = task_state_ready;		return (ISC_TRUE);	}	return (ISC_FALSE);}voidisc_task_detach(isc_task_t **taskp) {	isc_task_t *task;	isc_boolean_t was_idle;	/*	 * Detach *taskp from its task.	 */	REQUIRE(taskp != NULL);	task = *taskp;	REQUIRE(VALID_TASK(task));	XTRACE("isc_task_detach");	LOCK(&task->lock);	was_idle = task_detach(task);	UNLOCK(&task->lock);	if (was_idle)		task_ready(task);	*taskp = NULL;}static inline isc_boolean_ttask_send(isc_task_t *task, isc_event_t **eventp) {	isc_boolean_t was_idle = ISC_FALSE;	isc_event_t *event;	/*	 * Caller must be holding the task lock.	 */	REQUIRE(eventp != NULL);	event = *eventp;	REQUIRE(event != NULL);	REQUIRE(event->ev_type > 0);	REQUIRE(task->state != task_state_done);	XTRACE("task_send");	if (task->state == task_state_idle) {		was_idle = ISC_TRUE;		INSIST(EMPTY(task->events));		task->state = task_state_ready;	}	INSIST(task->state == task_state_ready ||	       task->state == task_state_running);	ENQUEUE(task->events, event, ev_link);	*eventp = NULL;	return (was_idle);}voidisc_task_send(isc_task_t *task, isc_event_t **eventp) {	isc_boolean_t was_idle;	/*	 * Send '*event' to 'task'.	 */	REQUIRE(VALID_TASK(task));	XTRACE("isc_task_send");	/*	 * We're trying hard to hold locks for as short a time as possible.	 * We're also trying to hold as few locks as possible.  This is why	 * some processing is deferred until after the lock is released.	 */	LOCK(&task->lock);	was_idle = task_send(task, eventp);	UNLOCK(&task->lock);	if (was_idle) {		/*		 * We need to add this task to the ready queue.		 *		 * We've waited until now to do it because making a task		 * ready requires locking the manager.  If we tried to do		 * this while holding the task lock, we could deadlock.		 *		 * We've changed the state to ready, so no one else will		 * be trying to add this task to the ready queue.  The		 * only way to leave the ready state is by executing the		 * task.  It thus doesn't matter if events are added,		 * removed, or a shutdown is started in the interval		 * between the time we released the task lock, and the time		 * we add the task to the ready queue.		 */		task_ready(task);	}}voidisc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) {	isc_boolean_t idle1, idle2;	isc_task_t *task;	/*

⌨️ 快捷键说明

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