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

📄 rwlock.c

📁 bind 9.3结合mysql数据库
💻 C
字号:
/* * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001, 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: rwlock.c,v 1.33.2.4.2.1 2004/03/06 08:14:35 marka Exp $ */#include <config.h>#include <stddef.h>#include <isc/magic.h>#include <isc/msgs.h>#include <isc/platform.h>#include <isc/rwlock.h>#include <isc/util.h>#define RWLOCK_MAGIC		ISC_MAGIC('R', 'W', 'L', 'k')#define VALID_RWLOCK(rwl)	ISC_MAGIC_VALID(rwl, RWLOCK_MAGIC)#ifdef ISC_PLATFORM_USETHREADS#ifndef RWLOCK_DEFAULT_READ_QUOTA#define RWLOCK_DEFAULT_READ_QUOTA 4#endif#ifndef RWLOCK_DEFAULT_WRITE_QUOTA#define RWLOCK_DEFAULT_WRITE_QUOTA 4#endif#ifdef ISC_RWLOCK_TRACE#include <stdio.h>		/* Required for fprintf/stderr. */#include <isc/thread.h>		/* Requried for isc_thread_self(). */static voidprint_lock(const char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) {	fprintf(stderr,		isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,			       ISC_MSG_PRINTLOCK,			       "rwlock %p thread %lu %s(%s): %s, %u active, "			       "%u granted, %u rwaiting, %u wwaiting\n"),		rwl, isc_thread_self(), operation,		(type == isc_rwlocktype_read ? 		 isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,				ISC_MSG_READ, "read") :		 isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,				ISC_MSG_WRITE, "write")),	        (rwl->type == isc_rwlocktype_read ?		 isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,				ISC_MSG_READING, "reading") : 		 isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,				ISC_MSG_WRITING, "writing")),	        rwl->active, rwl->granted, rwl->readers_waiting,		rwl->writers_waiting);}#endifisc_result_tisc_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->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;	result = isc_mutex_init(&rwl->lock);	if (result != ISC_R_SUCCESS) {		UNEXPECTED_ERROR(__FILE__, __LINE__,				 "isc_mutex_init() %s: %s",				 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,						ISC_MSG_FAILED, "failed"),				 isc_result_totext(result));		return (ISC_R_UNEXPECTED);	}	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));		return (ISC_R_UNEXPECTED);	}	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));		return (ISC_R_UNEXPECTED);	}	rwl->magic = RWLOCK_MAGIC;	return (ISC_R_SUCCESS);}static isc_result_tdoit(isc_rwlock_t *rwl, isc_rwlocktype_t type, isc_boolean_t nonblock) {	isc_boolean_t skip = ISC_FALSE;	isc_boolean_t done = ISC_FALSE;	isc_result_t result = ISC_R_SUCCESS;	REQUIRE(VALID_RWLOCK(rwl));	LOCK(&rwl->lock);#ifdef ISC_RWLOCK_TRACE	print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,				  ISC_MSG_PRELOCK, "prelock"), rwl, type);#endif	if (type == isc_rwlocktype_read) {		if (rwl->readers_waiting != 0)			skip = ISC_TRUE;		while (!done) {			if (!skip &&			    ((rwl->active == 0 ||			      (rwl->type == isc_rwlocktype_read &&			       (rwl->writers_waiting == 0 ||			        rwl->granted < rwl->read_quota)))))			{				rwl->type = isc_rwlocktype_read;				rwl->active++;				rwl->granted++;				done = ISC_TRUE;			} else if (nonblock) {				result = ISC_R_LOCKBUSY;				done = ISC_TRUE;			} else {				skip = ISC_FALSE;				rwl->readers_waiting++;				WAIT(&rwl->readable, &rwl->lock);				rwl->readers_waiting--;			}		}	} else {		if (rwl->writers_waiting != 0)			skip = ISC_TRUE;		while (!done) {			if (!skip && rwl->active == 0) {				rwl->type = isc_rwlocktype_write;				rwl->active = 1;				rwl->granted++;				done = ISC_TRUE;			} else if (nonblock) {				result = ISC_R_LOCKBUSY;				done = ISC_TRUE;			} else {				skip = ISC_FALSE;				rwl->writers_waiting++;				WAIT(&rwl->writeable, &rwl->lock);				rwl->writers_waiting--;			}		}	}#ifdef ISC_RWLOCK_TRACE	print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,				  ISC_MSG_POSTLOCK, "postlock"), rwl, type);#endif	UNLOCK(&rwl->lock);	return (result);}isc_result_tisc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {	return (doit(rwl, type, ISC_FALSE));}isc_result_tisc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {	return (doit(rwl, type, ISC_TRUE));}isc_result_tisc_rwlock_tryupgrade(isc_rwlock_t *rwl) {	isc_result_t result = ISC_R_SUCCESS;	REQUIRE(VALID_RWLOCK(rwl));	LOCK(&rwl->lock);	REQUIRE(rwl->type == isc_rwlocktype_read);	REQUIRE(rwl->active != 0);	/* If we are the only reader then succeed. */	if (rwl->active == 1) {		rwl->original = (rwl->original == isc_rwlocktype_none) ?				isc_rwlocktype_read : isc_rwlocktype_none;		rwl->type = isc_rwlocktype_write;	} else		result = ISC_R_LOCKBUSY;	UNLOCK(&rwl->lock);	return (result);}voidisc_rwlock_downgrade(isc_rwlock_t *rwl) {	REQUIRE(VALID_RWLOCK(rwl));	LOCK(&rwl->lock);	REQUIRE(rwl->type == isc_rwlocktype_write);	REQUIRE(rwl->active == 1);	rwl->type = isc_rwlocktype_read;	rwl->original = (rwl->original == isc_rwlocktype_none) ?			isc_rwlocktype_write : isc_rwlocktype_none;	/*	 * Resume processing any read request that were blocked when	 * we upgraded.	 */	if (rwl->original == isc_rwlocktype_none &&	    (rwl->writers_waiting == 0 || rwl->granted < rwl->read_quota) &&	    rwl->readers_waiting > 0)		BROADCAST(&rwl->readable);	UNLOCK(&rwl->lock);}isc_result_tisc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {	REQUIRE(VALID_RWLOCK(rwl));	LOCK(&rwl->lock);	REQUIRE(rwl->type == type);	UNUSED(type);#ifdef ISC_RWLOCK_TRACE	print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,				  ISC_MSG_PREUNLOCK, "preunlock"), rwl, type);#endif	INSIST(rwl->active > 0);	rwl->active--;	if (rwl->active == 0) {		if (rwl->original != isc_rwlocktype_none) {			rwl->type = rwl->original;			rwl->original = isc_rwlocktype_none;		}		if (rwl->type == isc_rwlocktype_read) {			rwl->granted = 0;			if (rwl->writers_waiting > 0) {				rwl->type = isc_rwlocktype_write;				SIGNAL(&rwl->writeable);			} else if (rwl->readers_waiting > 0) {				/* Does this case ever happen? */				BROADCAST(&rwl->readable);			}		} else {			if (rwl->readers_waiting > 0) {				if (rwl->writers_waiting > 0 &&				    rwl->granted < rwl->write_quota) {					SIGNAL(&rwl->writeable);				} else {					rwl->granted = 0;					rwl->type = isc_rwlocktype_read;					BROADCAST(&rwl->readable);				}			} else if (rwl->writers_waiting > 0) {				rwl->granted = 0;				SIGNAL(&rwl->writeable);			} else {				rwl->granted = 0;			}		}	}	INSIST(rwl->original == isc_rwlocktype_none);#ifdef ISC_RWLOCK_TRACE	print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,				  ISC_MSG_POSTUNLOCK, "postunlock"),		   rwl, type);#endif	UNLOCK(&rwl->lock);	return (ISC_R_SUCCESS);}voidisc_rwlock_destroy(isc_rwlock_t *rwl) {	REQUIRE(VALID_RWLOCK(rwl));	LOCK(&rwl->lock);	REQUIRE(rwl->active == 0 &&		rwl->readers_waiting == 0 &&		rwl->writers_waiting == 0);	UNLOCK(&rwl->lock);	rwl->magic = 0;	(void)isc_condition_destroy(&rwl->readable);	(void)isc_condition_destroy(&rwl->writeable);	DESTROYLOCK(&rwl->lock);}#else /* ISC_PLATFORM_USETHREADS */isc_result_tisc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,		unsigned int write_quota){	REQUIRE(rwl != NULL);	UNUSED(read_quota);	UNUSED(write_quota);	rwl->type = isc_rwlocktype_read;	rwl->active = 0;	rwl->magic = RWLOCK_MAGIC;	return (ISC_R_SUCCESS);}isc_result_tisc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {	REQUIRE(VALID_RWLOCK(rwl));	if (type == isc_rwlocktype_read) {		if (rwl->type != isc_rwlocktype_read && rwl->active != 0)			return (ISC_R_LOCKBUSY);		rwl->type = isc_rwlocktype_read;		rwl->active++;	} else {		if (rwl->active != 0)			return (ISC_R_LOCKBUSY);		rwl->type = isc_rwlocktype_write;		rwl->active = 1;	}        return (ISC_R_SUCCESS);}isc_result_tisc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {	return (isc_rwlock_lock(rwl, type));}isc_result_tisc_rwlock_tryupgrade(isc_rwlock_t *rwl) {	isc_result_t result = ISC_R_SUCCESS;	REQUIRE(VALID_RWLOCK(rwl));	REQUIRE(rwl->type == isc_rwlocktype_read);	REQUIRE(rwl->active != 0);		/* If we are the only reader then succeed. */	if (rwl->active == 1)		rwl->type = isc_rwlocktype_write;	else		result = ISC_R_LOCKBUSY;	return (result);}voidisc_rwlock_downgrade(isc_rwlock_t *rwl) {	REQUIRE(VALID_RWLOCK(rwl));	REQUIRE(rwl->type == isc_rwlocktype_write);	REQUIRE(rwl->active == 1);	rwl->type = isc_rwlocktype_read;}isc_result_tisc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {	REQUIRE(VALID_RWLOCK(rwl));	REQUIRE(rwl->type == type);	UNUSED(type);	INSIST(rwl->active > 0);	rwl->active--;	return (ISC_R_SUCCESS);}voidisc_rwlock_destroy(isc_rwlock_t *rwl) {	REQUIRE(rwl != NULL);	REQUIRE(rwl->active == 0);	rwl->magic = 0;}#endif /* ISC_PLATFORM_USETHREADS */

⌨️ 快捷键说明

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