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

📄 db_iface.c

📁 这是国外的resip协议栈
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (handle_check)		__env_db_rep_exit(dbenv);	return (ret);}/* * __db_c_get_arg -- *	Common DBC->get argument checking, used by both DBC->get and DBC->pget. */static int__db_c_get_arg(dbc, key, data, flags)	DBC *dbc;	DBT *key, *data;	u_int32_t flags;{	DB *dbp;	DB_ENV *dbenv;	int dirty, multi, ret;	dbp = dbc->dbp;	dbenv = dbp->dbenv;	/*	 * Typically in checking routines that modify the flags, we have	 * to save them and restore them, because the checking routine	 * calls the work routine.  However, this is a pure-checking	 * routine which returns to a function that calls the work routine,	 * so it's OK that we do not save and restore the flags, even though	 * we modify them.	 *	 * Check for read-modify-write validity.  DB_RMW doesn't make sense	 * with CDB cursors since if you're going to write the cursor, you	 * had to create it with DB_WRITECURSOR.  Regardless, we check for	 * LOCKING_ON and not STD_LOCKING, as we don't want to disallow it.	 * If this changes, confirm that DB does not itself set the DB_RMW	 * flag in a path where CDB may have been configured.	 */	dirty = 0;	if (LF_ISSET(DB_DIRTY_READ | DB_RMW)) {		if (!LOCKING_ON(dbenv))			return (__db_fnl(dbenv, "DBcursor->get"));		if (LF_ISSET(DB_DIRTY_READ))			dirty = 1;		LF_CLR(DB_DIRTY_READ | DB_RMW);	}	multi = 0;	if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) {		multi = 1;		if (LF_ISSET(DB_MULTIPLE) && LF_ISSET(DB_MULTIPLE_KEY))			goto multi_err;		LF_CLR(DB_MULTIPLE | DB_MULTIPLE_KEY);	}	/* Check for invalid function flags. */	switch (flags) {	case DB_CONSUME:	case DB_CONSUME_WAIT:		if (dirty) {			__db_err(dbenv,    "DB_DIRTY_READ is not supported with DB_CONSUME or DB_CONSUME_WAIT");			return (EINVAL);		}		if (dbp->type != DB_QUEUE)			goto err;		break;	case DB_CURRENT:	case DB_FIRST:	case DB_GET_BOTH:	case DB_GET_BOTH_RANGE:	case DB_NEXT:	case DB_NEXT_DUP:	case DB_NEXT_NODUP:	case DB_SET:	case DB_SET_RANGE:		break;	case DB_LAST:	case DB_PREV:	case DB_PREV_NODUP:		if (multi)multi_err:		return (__db_ferr(dbenv, "DBcursor->get", 1));		break;	case DB_GET_BOTHC:		if (dbp->type == DB_QUEUE)			goto err;		break;	case DB_GET_RECNO:		/*		 * The one situation in which this might be legal with a		 * non-RECNUM dbp is if dbp is a secondary and its primary is		 * DB_AM_RECNUM.		 */		if (!F_ISSET(dbp, DB_AM_RECNUM) &&		    (!F_ISSET(dbp, DB_AM_SECONDARY) ||		    !F_ISSET(dbp->s_primary, DB_AM_RECNUM)))			goto err;		break;	case DB_SET_RECNO:		if (!F_ISSET(dbp, DB_AM_RECNUM))			goto err;		break;	default:err:		return (__db_ferr(dbenv, "DBcursor->get", 0));	}	/* Check for invalid key/data flags. */	if ((ret = __dbt_ferr(dbp, "key", key, 0)) != 0)		return (ret);	if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0)		return (ret);	if (multi) {		if (!F_ISSET(data, DB_DBT_USERMEM)) {			__db_err(dbenv,	    "DB_MULTIPLE/DB_MULTIPLE_KEY require DB_DBT_USERMEM be set");			return (EINVAL);		}		if (F_ISSET(key, DB_DBT_PARTIAL) ||		    F_ISSET(data, DB_DBT_PARTIAL)) {			__db_err(dbenv,	    "DB_MULTIPLE/DB_MULTIPLE_KEY do not support DB_DBT_PARTIAL");			return (EINVAL);		}		if (data->ulen < 1024 ||		    data->ulen < dbp->pgsize || data->ulen % 1024 != 0) {			__db_err(dbenv, "%s%s",			    "DB_MULTIPLE/DB_MULTIPLE_KEY buffers must be ",			    "aligned, at least page size and multiples of 1KB");			return (EINVAL);		}	}	/*	 * The cursor must be initialized for DB_CURRENT, DB_GET_RECNO and	 * DB_NEXT_DUP.  Return EINVAL for an invalid cursor, otherwise 0.	 */	if (!IS_INITIALIZED(dbc) && (flags == DB_CURRENT ||	    flags == DB_GET_RECNO || flags == DB_NEXT_DUP))		return (__db_curinval(dbenv));	/* Check for consistent transaction usage. */	if (LF_ISSET(DB_RMW) &&	    (ret = __db_check_txn(dbp, dbc->txn, dbc->locker, 0)) != 0)		return (ret);	return (0);}/* * __db_secondary_close_pp -- *	DB->close for secondaries * * PUBLIC: int __db_secondary_close_pp __P((DB *, u_int32_t)); */int__db_secondary_close_pp(dbp, flags)	DB *dbp;	u_int32_t flags;{	DB_ENV *dbenv;	int handle_check, ret, t_ret;	dbenv = dbp->dbenv;	ret = 0;	PANIC_CHECK(dbenv);	/*	 * !!!	 * The actual argument checking is simple, do it inline.	 *	 * Validate arguments and complain if they're wrong, but as a DB	 * handle destructor, we can't fail.	 */	if (flags != 0 && flags != DB_NOSYNC &&	    (t_ret = __db_ferr(dbenv, "DB->close", 0)) != 0 && ret == 0)		ret = t_ret;	/* Check for replication block. */	handle_check = IS_REPLICATED(dbenv, dbp);	if (handle_check &&	    (t_ret = __db_rep_enter(dbp, 0, 0, 0)) != 0) {		handle_check = 0;		if (ret == 0)			ret = t_ret;	}	if ((t_ret = __db_secondary_close(dbp, flags)) != 0 && ret == 0)		ret = t_ret;	/* Release replication block. */	if (handle_check)		__env_db_rep_exit(dbenv);	return (ret);}/* * __db_c_pget_pp -- *	DBC->c_pget pre/post processing. * * PUBLIC: int __db_c_pget_pp __P((DBC *, DBT *, DBT *, DBT *, u_int32_t)); */int__db_c_pget_pp(dbc, skey, pkey, data, flags)	DBC *dbc;	DBT *skey, *pkey, *data;	u_int32_t flags;{	DB *dbp;	DB_ENV *dbenv;	int handle_check, ret;	dbp = dbc->dbp;	dbenv = dbp->dbenv;	PANIC_CHECK(dbenv);	if ((ret = __db_c_pget_arg(dbc, pkey, flags)) != 0)		return (ret);	if ((ret = __db_c_get_arg(dbc, skey, data, flags)) != 0)		return (ret);	/* Check for replication block. */	handle_check = IS_REPLICATED(dbenv, dbp);	if (handle_check &&	    (ret = __db_rep_enter(dbp, 1, 0, dbc->txn != NULL)) != 0)		return (ret);	ret = __db_c_pget(dbc, skey, pkey, data, flags);	/* Release replication block. */	if (handle_check)		__env_db_rep_exit(dbenv);	return (ret);}/* * __db_c_pget_arg -- *	Check DBC->pget arguments. */static int__db_c_pget_arg(dbc, pkey, flags)	DBC *dbc;	DBT *pkey;	u_int32_t flags;{	DB *dbp;	DB_ENV *dbenv;	int ret;	dbp = dbc->dbp;	dbenv = dbp->dbenv;	if (!F_ISSET(dbp, DB_AM_SECONDARY)) {		__db_err(dbenv,		    "DBcursor->pget may only be used on secondary indices");		return (EINVAL);	}	if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) {		__db_err(dbenv,	"DB_MULTIPLE and DB_MULTIPLE_KEY may not be used on secondary indices");		return (EINVAL);	}	switch (LF_ISSET(~DB_RMW)) {	case DB_CONSUME:	case DB_CONSUME_WAIT:		/* These flags make no sense on a secondary index. */		return (__db_ferr(dbenv, "DBcursor->pget", 0));	case DB_GET_BOTH:		/* DB_GET_BOTH is "get both the primary and the secondary". */		if (pkey == NULL) {			__db_err(dbenv,		    "DB_GET_BOTH requires both a secondary and a primary key");			return (EINVAL);		}		break;	default:		/* __db_c_get_arg will catch the rest. */		break;	}	/*	 * We allow the pkey field to be NULL, so that we can make the	 * two-DBT get calls into wrappers for the three-DBT ones.	 */	if (pkey != NULL &&	    (ret = __dbt_ferr(dbp, "primary key", pkey, 0)) != 0)		return (ret);	/* But the pkey field can't be NULL if we're doing a DB_GET_BOTH. */	if (pkey == NULL && (flags & DB_OPFLAGS_MASK) == DB_GET_BOTH) {		__db_err(dbenv,		    "DB_GET_BOTH on a secondary index requires a primary key");		return (EINVAL);	}	return (0);}/* * __db_c_put_pp -- *	DBC->put pre/post processing. * * PUBLIC: int __db_c_put_pp __P((DBC *, DBT *, DBT *, u_int32_t)); */int__db_c_put_pp(dbc, key, data, flags)	DBC *dbc;	DBT *key, *data;	u_int32_t flags;{	DB *dbp;	DB_ENV *dbenv;	int handle_check, ret;	dbp = dbc->dbp;	dbenv = dbp->dbenv;	PANIC_CHECK(dbenv);	if ((ret = __db_c_put_arg(dbc, key, data, flags)) != 0)		return (ret);	/* Check for consistent transaction usage. */	if ((ret = __db_check_txn(dbp, dbc->txn, dbc->locker, 0)) != 0)		return (ret);	/* Check for replication block. */	handle_check = IS_REPLICATED(dbenv, dbp);	if (handle_check &&	    (ret = __db_rep_enter(dbp, 1, 0, dbc->txn != NULL)) != 0)		return (ret);	DEBUG_LWRITE(dbc, dbc->txn, "DBcursor->put",	    flags == DB_KEYFIRST || flags == DB_KEYLAST ||	    flags == DB_NODUPDATA || flags == DB_UPDATE_SECONDARY ?	    key : NULL, data, flags);	ret =__db_c_put(dbc, key, data, flags);	/* Release replication block. */	if (handle_check)		__env_db_rep_exit(dbenv);	return (ret);}/* * __db_c_put_arg -- *	Check DBC->put arguments. */static int__db_c_put_arg(dbc, key, data, flags)	DBC *dbc;	DBT *key, *data;	u_int32_t flags;{	DB *dbp;	DB_ENV *dbenv;	int key_flags, ret;	dbp = dbc->dbp;	dbenv = dbp->dbenv;	key_flags = 0;	/* Check for changes to a read-only tree. */	if (IS_READONLY(dbp))		return (__db_rdonly(dbenv, "c_put"));	/* Check for puts on a secondary. */	if (F_ISSET(dbp, DB_AM_SECONDARY)) {		if (flags == DB_UPDATE_SECONDARY)			flags = DB_KEYLAST;		else {			__db_err(dbenv,		    "DBcursor->put forbidden on secondary indices");			return (EINVAL);		}	}	/* Check for invalid function flags. */	switch (flags) {	case DB_AFTER:	case DB_BEFORE:		switch (dbp->type) {		case DB_BTREE:		case DB_HASH:		/* Only with unsorted duplicates. */			if (!F_ISSET(dbp, DB_AM_DUP))				goto err;			if (dbp->dup_compare != NULL)				goto err;			break;		case DB_QUEUE:		/* Not permitted. */			goto err;		case DB_RECNO:		/* Only with mutable record numbers. */			if (!F_ISSET(dbp, DB_AM_RENUMBER))				goto err;			key_flags = 1;			break;		case DB_UNKNOWN:		default:			goto err;		}		break;	case DB_CURRENT:		/*		 * If there is a comparison function, doing a DB_CURRENT		 * must not change the part of the data item that is used		 * for the comparison.		 */		break;	case DB_NODUPDATA:		if (!F_ISSET(dbp, DB_AM_DUPSORT))			goto err;		/* FALLTHROUGH */	case DB_KEYFIRST:	case DB_KEYLAST:		key_flags = 1;		break;	default:err:		return (__db_ferr(dbenv, "DBcursor->put", 0));	}	/* Check for invalid key/data flags. */	if (key_flags && (ret = __dbt_ferr(dbp, "key", key, 0)) != 0)		return (ret);	if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0)		return (ret);	/* Keys shouldn't have partial flags during a put. */	if (F_ISSET(key, DB_DBT_PARTIAL))		return (__db_ferr(dbenv, "key DBT", 0));	/*	 * The cursor must be initialized for anything other than DB_KEYFIRST	 * and DB_KEYLAST, return EINVAL for an invalid cursor, otherwise 0.	 */	if (!IS_INITIALIZED(dbc) && flags != DB_KEYFIRST &&	    flags != DB_KEYLAST && flags != DB_NODUPDATA)		return (__db_curinval(dbenv));	return (0);}/* * __dbt_ferr -- *	Check a DBT for flag errors. */static int__dbt_ferr(dbp, name, dbt, check_thread)	const DB *dbp;	const char *name;	const DBT *dbt;	int check_thread;{	DB_ENV *dbenv;	int ret;	dbenv = dbp->dbenv;	/*	 * Check for invalid DBT flags.  We allow any of the flags to be	 * specified to any DB or DBcursor call so that applications can	 * set DB_DBT_MALLOC when retrieving a data item from a secondary	 * database and then specify that same DBT as a key to a primary	 * database, without having to clear flags.	 */	if ((ret = __db_fchk(dbenv, name, dbt->flags, DB_DBT_APPMALLOC |	    DB_DBT_MALLOC | DB_DBT_DUPOK | DB_DBT_REALLOC | DB_DBT_USERMEM |	    DB_DBT_PARTIAL)) != 0)		return (ret);	switch (F_ISSET(dbt, DB_DBT_MALLOC | DB_DBT_REALLOC | DB_DBT_USERMEM)) {	case 0:	case DB_DBT_MALLOC:	case DB_DBT_REALLOC:	case DB_DBT_USERMEM:		break;	default:		return (__db_ferr(dbenv, name, 1));	}	if (check_thread && DB_IS_THREADED(dbp) &&	    !F_ISSET(dbt, DB_DBT_MALLOC | DB_DBT_REALLOC | DB_DBT_USERMEM)) {		__db_err(dbenv,		    "DB_THREAD mandates memory allocation flag on DBT %s",		    name);		return (EINVAL);	}	return (0);}/* * __db_rdonly -- *	Common readonly message. */static int__db_rdonly(dbenv, name)	const DB_ENV *dbenv;	const char *name;{	__db_err(dbenv, "%s: attempt to modify a read-only tree", name);	return (EACCES);}/* * __db_curinval *	Report that a cursor is in an invalid state. */static int__db_curinval(dbenv)	const DB_ENV *dbenv;{	__db_err(dbenv,	    "Cursor position must be set before performing this operation");	return (EINVAL);}/* * __db_txn_auto_init -- *	Handle DB_AUTO_COMMIT initialization. * * PUBLIC: int __db_txn_auto_init __P((DB_ENV *, DB_TXN **)); */int__db_txn_auto_init(dbenv, txnidp)	DB_ENV *dbenv;	DB_TXN **txnidp;{	if (*txnidp != NULL) {		__db_err(dbenv,    "DB_AUTO_COMMIT may not be specified along with a transaction handle");		return (EINVAL);	}	if (!TXN_ON(dbenv)) {		__db_err(dbenv,    "DB_AUTO_COMMIT may not be specified in non-transactional environment");		return (EINVAL);	}	/*	 * We're creating a transaction for the user, and we want it to block	 * if replication recovery is running.  Call the user-level API.	 */	return (dbenv->txn_begin(dbenv, NULL, txnidp, 0));}/* * __db_txn_auto_resolve -- *	Handle DB_AUTO_COMMIT resolution. * * PUBLIC: int __db_txn_auto_resolve __P((DB_ENV *, DB_TXN *, int, int)); */int__db_txn_auto_resolve(dbenv, txn, nosync, ret)	DB_ENV *dbenv;	DB_TXN *txn;	int nosync, ret;{	int t_ret;	/*	 * We're resolving a transaction for the user, and must decrement the	 * replication handle count.  Call the user-level API.	 */	if (ret == 0)		return (txn->commit(txn, nosync ? DB_TXN_NOSYNC : 0));	if ((t_ret = txn->abort(txn)) != 0)		return (__db_panic(dbenv, t_ret));	return (ret);}

⌨️ 快捷键说明

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