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

📄 db.c

📁 这是国外的resip协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
	/* Discard the thread mutex. */	if (dbp->mutexp != NULL) {		dbmp = dbenv->mp_handle;		__db_mutex_free(dbenv, dbmp->reginfo, dbp->mutexp);		dbp->mutexp = NULL;	}	/* Discard any memory allocated for the file and database names. */	if (dbp->fname != NULL) {		__os_free(dbp->dbenv, dbp->fname);		dbp->fname = NULL;	}	if (dbp->dname != NULL) {		__os_free(dbp->dbenv, dbp->dname);		dbp->dname = NULL;	}	/* Discard any memory used to store returned data. */	if (dbp->my_rskey.data != NULL)		__os_free(dbp->dbenv, dbp->my_rskey.data);	if (dbp->my_rkey.data != NULL)		__os_free(dbp->dbenv, dbp->my_rkey.data);	if (dbp->my_rdata.data != NULL)		__os_free(dbp->dbenv, dbp->my_rdata.data);	/* For safety's sake;  we may refresh twice. */	memset(&dbp->my_rskey, 0, sizeof(DBT));	memset(&dbp->my_rkey, 0, sizeof(DBT));	memset(&dbp->my_rdata, 0, sizeof(DBT));	/* Clear out fields that normally get set during open. */	memset(dbp->fileid, 0, sizeof(dbp->fileid));	dbp->adj_fileid = 0;	dbp->meta_pgno = 0;	dbp->cur_lid = DB_LOCK_INVALIDID;	dbp->associate_lid = DB_LOCK_INVALIDID;	dbp->cl_id = 0;	dbp->open_flags = 0;	/*	 * If we are being refreshed with a txn specified, then we need	 * to make sure that we clear out the lock handle field, because	 * releasing all the locks for this transaction will release this	 * lock and we don't want close to stumble upon this handle and	 * try to close it.	 */	if (txn != NULL)		LOCK_INIT(dbp->handle_lock);	/* Reset flags to whatever the user configured. */	dbp->flags = dbp->orig_flags;	return (ret);}/* * __db_log_page *	Log a meta-data or root page during a subdatabase create operation. * * PUBLIC: int __db_log_page __P((DB *, DB_TXN *, DB_LSN *, db_pgno_t, PAGE *)); */int__db_log_page(dbp, txn, lsn, pgno, page)	DB *dbp;	DB_TXN *txn;	DB_LSN *lsn;	db_pgno_t pgno;	PAGE *page;{	DBT page_dbt;	DB_LSN new_lsn;	int ret;	if (!LOGGING_ON(dbp->dbenv) || txn == NULL)		return (0);	memset(&page_dbt, 0, sizeof(page_dbt));	page_dbt.size = dbp->pgsize;	page_dbt.data = page;	ret = __crdel_metasub_log(dbp, txn, &new_lsn, 0, pgno, &page_dbt, lsn);	if (ret == 0)		page->lsn = new_lsn;	return (ret);}/* * __db_backup_name *	Create the backup file name for a given file. * * PUBLIC: int __db_backup_name __P((DB_ENV *, * PUBLIC:     const char *, DB_TXN *, char **)); */#undef	BACKUP_PREFIX#define	BACKUP_PREFIX	"__db."#undef	MAX_LSN_TO_TEXT#define	MAX_LSN_TO_TEXT	17int__db_backup_name(dbenv, name, txn, backup)	DB_ENV *dbenv;	const char *name;	DB_TXN *txn;	char **backup;{	DB_LSN lsn;	size_t len;	int ret;	char *p, *retp;	/*	 * Part of the name may be a full path, so we need to make sure that	 * we allocate enough space for it, even in the case where we don't	 * use the entire filename for the backup name.	 */	len = strlen(name) + strlen(BACKUP_PREFIX) + MAX_LSN_TO_TEXT;	if ((ret = __os_malloc(dbenv, len, &retp)) != 0)		return (ret);	/*	 * Create the name.  Backup file names are in one of two forms:	 *	 *	In a transactional env: __db.LSN(8).LSN(8)	 * and	 *	in a non-transactional env: __db.FILENAME	 *	 * If the transaction doesn't have a current LSN, we write a dummy	 * log record to force it, so we ensure all tmp names are unique.	 *	 * In addition, the name passed may contain an env-relative path.	 * In that case, put the __db. in the right place (in the last	 * component of the pathname).	 *	 * There are four cases here:	 *	1. simple path w/out transaction	 *	2. simple path + transaction	 *	3. multi-component path w/out transaction	 *	4. multi-component path + transaction	 */	p = __db_rpath(name);	if (txn == NULL)		if (p == NULL)				/* Case 1. */			snprintf(retp, len, "%s%s", BACKUP_PREFIX, name);		else					/* Case 3. */			snprintf(retp, len, "%.*s%s%s",			    (int)(p - name) + 1, name, BACKUP_PREFIX, p + 1);	else {		if (IS_ZERO_LSN(txn->last_lsn)) {			/*			 * Write dummy log record.   The two choices for dummy			 * log records are __db_noop_log and __db_debug_log;			 * unfortunately __db_noop_log requires a valid dbp,			 * and we aren't guaranteed to be able to pass one in			 * here.			 */			if ((ret = __db_debug_log(dbenv,			    txn, &lsn, 0, NULL, 0, NULL, NULL, 0)) != 0) {				__os_free(dbenv, retp);				return (ret);			}		} else			lsn = txn->last_lsn;		if (p == NULL)				/* Case 2. */			snprintf(retp, len,			    "%s%x.%x", BACKUP_PREFIX, lsn.file, lsn.offset);		else					/* Case 4. */			snprintf(retp, len, "%.*s%x.%x",			    (int)(p - name) + 1, name, lsn.file, lsn.offset);	}	*backup = retp;	return (0);}/* * __dblist_get -- *	Get the first element of dbenv->dblist with *	dbp->adj_fileid matching adjid. * * PUBLIC: DB *__dblist_get __P((DB_ENV *, u_int32_t)); */DB *__dblist_get(dbenv, adjid)	DB_ENV *dbenv;	u_int32_t adjid;{	DB *dbp;	for (dbp = LIST_FIRST(&dbenv->dblist);	    dbp != NULL && dbp->adj_fileid != adjid;	    dbp = LIST_NEXT(dbp, dblistlinks))		;	return (dbp);}/* * __db_disassociate -- *	Destroy the association between a given secondary and its primary. */static int__db_disassociate(sdbp)	DB *sdbp;{	DBC *dbc;	int ret, t_ret;	ret = 0;	sdbp->s_callback = NULL;	sdbp->s_primary = NULL;	sdbp->get = sdbp->stored_get;	sdbp->close = sdbp->stored_close;	/*	 * Complain, but proceed, if we have any active cursors.  (We're in	 * the middle of a close, so there's really no turning back.)	 */	if (sdbp->s_refcnt != 1 ||	    TAILQ_FIRST(&sdbp->active_queue) != NULL ||	    TAILQ_FIRST(&sdbp->join_queue) != NULL) {		__db_err(sdbp->dbenv,    "Closing a primary DB while a secondary DB has active cursors is unsafe");		ret = EINVAL;	}	sdbp->s_refcnt = 0;	while ((dbc = TAILQ_FIRST(&sdbp->free_queue)) != NULL)		if ((t_ret = __db_c_destroy(dbc)) != 0 && ret == 0)			ret = t_ret;	F_CLR(sdbp, DB_AM_SECONDARY);	return (ret);}#ifdef CONFIG_TEST/* * __db_testcopy *	Create a copy of all backup files and our "main" DB. * * PUBLIC: #ifdef CONFIG_TEST * PUBLIC: int __db_testcopy __P((DB_ENV *, DB *, const char *)); * PUBLIC: #endif */int__db_testcopy(dbenv, dbp, name)	DB_ENV *dbenv;	DB *dbp;	const char *name;{	DB_MPOOL *dbmp;	DB_MPOOLFILE *mpf;	DB_ASSERT(dbp != NULL || name != NULL);	if (name == NULL) {		dbmp = dbenv->mp_handle;		mpf = dbp->mpf;		name = R_ADDR(dbmp->reginfo, mpf->mfp->path_off);	}	if (dbp != NULL && dbp->type == DB_QUEUE)		return (__qam_testdocopy(dbp, name));	else		return (__db_testdocopy(dbenv, name));}static int__qam_testdocopy(dbp, name)	DB *dbp;	const char *name;{	QUEUE_FILELIST *filelist, *fp;	char buf[256], *dir;	int ret;	filelist = NULL;	if ((ret = __db_testdocopy(dbp->dbenv, name)) != 0)		return (ret);	if (dbp->mpf != NULL &&	    (ret = __qam_gen_filelist(dbp, &filelist)) != 0)		return (ret);	if (filelist == NULL)		return (0);	dir = ((QUEUE *)dbp->q_internal)->dir;	for (fp = filelist; fp->mpf != NULL; fp++) {		snprintf(buf, sizeof(buf),		    QUEUE_EXTENT, dir, PATH_SEPARATOR[0], name, fp->id);		if ((ret = __db_testdocopy(dbp->dbenv, buf)) != 0)			return (ret);	}	__os_free(dbp->dbenv, filelist);	return (0);}/* * __db_testdocopy *	Create a copy of all backup files and our "main" DB. * */static int__db_testdocopy(dbenv, name)	DB_ENV *dbenv;	const char *name;{	size_t len;	int dircnt, i, ret;	char *backup, *copy, *dir, **namesp, *p, *real_name;	dircnt = 0;	copy = backup = NULL;	namesp = NULL;	/* Get the real backing file name. */	if ((ret = __db_appname(dbenv,	    DB_APP_DATA, name, 0, NULL, &real_name)) != 0)		return (ret);	/*	 * Maximum size of file, including adding a ".afterop".	 */	len = strlen(real_name) + strlen(BACKUP_PREFIX) + MAX_LSN_TO_TEXT + 9;	if ((ret = __os_malloc(dbenv, len, &copy)) != 0)		goto err;	if ((ret = __os_malloc(dbenv, len, &backup)) != 0)		goto err;	/*	 * First copy the file itself.	 */	snprintf(copy, len, "%s.afterop", real_name);	__db_makecopy(dbenv, real_name, copy);	if ((ret = __os_strdup(dbenv, real_name, &dir)) != 0)		goto err;	__os_free(dbenv, real_name);	real_name = NULL;	/*	 * Create the name.  Backup file names are of the form:	 *	 *	__db.name.0x[lsn-file].0x[lsn-offset]	 *	 * which guarantees uniqueness.  We want to look for the	 * backup name, followed by a '.0x' (so that if they have	 * files named, say, 'a' and 'abc' we won't match 'abc' when	 * looking for 'a'.	 */	snprintf(backup, len, "%s%s.0x", BACKUP_PREFIX, name);	/*	 * We need the directory path to do the __os_dirlist.	 */	p = __db_rpath(dir);	if (p != NULL)		*p = '\0';	ret = __os_dirlist(dbenv, dir, &namesp, &dircnt);#if DIAGNOSTIC	/*	 * XXX	 * To get the memory guard code to work because it uses strlen and we	 * just moved the end of the string somewhere sooner.  This causes the	 * guard code to fail because it looks at one byte past the end of the	 * string.	 */	*p = '/';#endif	__os_free(dbenv, dir);	if (ret != 0)		goto err;	for (i = 0; i < dircnt; i++) {		/*		 * Need to check if it is a backup file for this.		 * No idea what namesp[i] may be or how long, so		 * must use strncmp and not memcmp.  We don't want		 * to use strcmp either because we are only matching		 * the first part of the real file's name.  We don't		 * know its LSN's.		 */		if (strncmp(namesp[i], backup, strlen(backup)) == 0) {			if ((ret = __db_appname(dbenv, DB_APP_DATA,			    namesp[i], 0, NULL, &real_name)) != 0)				goto err;			/*			 * This should not happen.  Check that old			 * .afterop files aren't around.			 * If so, just move on.			 */			if (strstr(real_name, ".afterop") != NULL) {				__os_free(dbenv, real_name);				real_name = NULL;				continue;			}			snprintf(copy, len, "%s.afterop", real_name);			__db_makecopy(dbenv, real_name, copy);			__os_free(dbenv, real_name);			real_name = NULL;		}	}err:	if (backup != NULL)		__os_free(dbenv, backup);	if (copy != NULL)		__os_free(dbenv, copy);	if (namesp != NULL)		__os_dirfree(dbenv, namesp, dircnt);	if (real_name != NULL)		__os_free(dbenv, real_name);	return (ret);}static void__db_makecopy(dbenv, src, dest)	DB_ENV *dbenv;	const char *src, *dest;{	DB_FH *rfhp, *wfhp;	size_t rcnt, wcnt;	char *buf;	rfhp = wfhp = NULL;	if (__os_malloc(dbenv, 1024, &buf) != 0)		return;	if (__os_open(dbenv,	    src, DB_OSO_RDONLY, __db_omode("rw----"), &rfhp) != 0)		goto err;	if (__os_open(dbenv, dest,	    DB_OSO_CREATE | DB_OSO_TRUNC, __db_omode("rw----"), &wfhp) != 0)		goto err;	for (;;)		if (__os_read(dbenv, rfhp, buf, 1024, &rcnt) < 0 || rcnt == 0 ||		    __os_write(dbenv, wfhp, buf, rcnt, &wcnt) < 0)			break;err:	if (buf != NULL)		__os_free(dbenv, buf);	if (rfhp != NULL)		(void)__os_closehandle(dbenv, rfhp);	if (wfhp != NULL)		(void)__os_closehandle(dbenv, wfhp);}#endif

⌨️ 快捷键说明

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