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

📄 qam.c

📁 这是国外的resip协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
	return ((ret == DB_LOCK_NOTGRANTED &&	     !F_ISSET(dbenv, DB_ENV_TIME_NOTGRANTED)) ?	     DB_LOCK_DEADLOCK : ret);}/* * __qam_consume -- try to reset the head of the queue. * */static int__qam_consume(dbc, meta, first)	DBC *dbc;	QMETA *meta;	db_recno_t first;{	DB *dbp;	DB_LOCK lock, save_lock;	DB_MPOOLFILE *mpf;	QUEUE_CURSOR *cp;	db_indx_t save_indx;	db_pgno_t save_page;	db_recno_t current, save_recno;	u_int32_t put_mode, rec_extent;	int exact, ret, t_ret, wrapped;	dbp = dbc->dbp;	mpf = dbp->mpf;	cp = (QUEUE_CURSOR *)dbc->internal;	put_mode = DB_MPOOL_DIRTY;	ret = 0;	save_page = cp->pgno;	save_indx = cp->indx;	save_recno = cp->recno;	save_lock = cp->lock;	/*	 * If we skipped some deleted records, we need to	 * reposition on the first one.  Get a lock	 * in case someone is trying to put it back.	 */	if (first != cp->recno) {		ret = __db_lget(dbc, 0, first, DB_LOCK_READ,		    DB_LOCK_NOWAIT | DB_LOCK_RECORD, &lock);		if (ret == DB_LOCK_DEADLOCK) {			ret = 0;			goto done;		}		if (ret != 0)			goto done;		if ((ret =		    __qam_fput(dbp, cp->pgno, cp->page, put_mode)) != 0)			goto done;		cp->page = NULL;		put_mode = 0;		if ((ret = __qam_position(dbc,		    &first, QAM_READ, &exact)) != 0 || exact != 0) {			(void)__LPUT(dbc, lock);			goto done;		}		if ((ret =__LPUT(dbc, lock)) != 0)			goto done;		if ((ret = __LPUT(dbc, cp->lock)) != 0)			goto done;	}	current = meta->cur_recno;	wrapped = 0;	if (first > current)		wrapped = 1;	rec_extent = meta->page_ext * meta->rec_page;	/* Loop until we find a record or hit current */	for (;;) {		/*		 * Check to see if we are moving off the extent		 * and remove the extent.		 * If we are moving off a page we need to		 * get rid of the buffer.		 * Wait for the lagging readers to move off the		 * page.		 */		if (cp->page != NULL && rec_extent != 0 &&		    ((exact = (first % rec_extent == 0)) ||		    first % meta->rec_page == 0 ||		    first == UINT32_MAX)) {			if (exact == 1 && (ret = __db_lget(dbc,			    0, cp->pgno, DB_LOCK_WRITE, 0, &cp->lock)) != 0)				break;#ifdef QDEBUG			__db_logmsg(dbp->dbenv,			    dbc->txn, "Queue R", 0, "%x %d %d %d",			    dbc->locker, cp->pgno, first, meta->first_recno);#endif			put_mode |= DB_MPOOL_DISCARD;			if ((ret = __qam_fput(dbp,			    cp->pgno, cp->page, put_mode)) != 0)				break;			cp->page = NULL;			if (exact == 1) {				ret = __qam_fremove(dbp, cp->pgno);				if ((t_ret =				    __LPUT(dbc, cp->lock)) != 0 && ret == 0)					ret = t_ret;			}			if (ret != 0)				break;		} else if (cp->page != NULL && (ret =		    __qam_fput(dbp, cp->pgno, cp->page, put_mode)) != 0)			break;		cp->page = NULL;		first++;		if (first == RECNO_OOB) {			wrapped = 0;			first++;		}		/*		 * LOOP EXIT when we come move to the current		 * pointer.		 */		if (!wrapped && first >= current)			break;		ret = __db_lget(dbc, 0, first, DB_LOCK_READ,		    DB_LOCK_NOWAIT | DB_LOCK_RECORD, &lock);		if (ret == DB_LOCK_DEADLOCK) {			ret = 0;			break;		}		if (ret != 0)			break;		if ((ret = __qam_position(dbc,		    &first, QAM_READ, &exact)) != 0) {			(void)__LPUT(dbc, lock);			break;		}		put_mode = 0;		if ((ret =__LPUT(dbc, lock)) != 0 ||		    (ret = __LPUT(dbc, cp->lock)) != 0 || exact) {			if ((t_ret = __qam_fput(dbp, cp->pgno,			    cp->page, put_mode)) != 0 && ret == 0)				ret = t_ret;			cp->page = NULL;			break;		}	}	cp->pgno = save_page;	cp->indx = save_indx;	cp->recno = save_recno;	cp->lock = save_lock;	/*	 * We have advanced as far as we can.	 * Advance first_recno to this point.	 */	if (ret == 0 && meta->first_recno != first) {#ifdef QDEBUG		__db_logmsg(dbp->dbenv, dbc->txn, "Queue M",		    0, "%x %d %d %d", dbc->locker, cp->recno,		    first, meta->first_recno);#endif		if (DBC_LOGGING(dbc))			if ((ret = __qam_incfirst_log(dbp,			    dbc->txn, &meta->dbmeta.lsn, 0,			    cp->recno, PGNO_BASE_MD)) != 0)				goto done;		meta->first_recno = first;		(void)__memp_fset(mpf, meta, DB_MPOOL_DIRTY);	}done:	return (ret);}static int__qam_bulk(dbc, data, flags)	DBC *dbc;	DBT *data;	u_int32_t flags;{	DB *dbp;	DB_LOCK metalock, rlock;	DB_MPOOLFILE *mpf;	PAGE *pg;	QMETA *meta;	QAMDATA *qp;	QUEUE_CURSOR *cp;	db_indx_t indx;	db_lockmode_t lkmode;	db_pgno_t metapno;	qam_position_mode mode;	int32_t  *endp, *offp;	u_int8_t *dbuf, *dp, *np;	int exact, recs, re_len, ret, t_ret, valid;	int is_key, need_pg, pagesize, size, space;	dbp = dbc->dbp;	mpf = dbp->mpf;	cp = (QUEUE_CURSOR *)dbc->internal;	mode = QAM_READ;	lkmode = DB_LOCK_READ;	if (F_ISSET(dbc, DBC_RMW)) {		mode = QAM_WRITE;		lkmode = DB_LOCK_WRITE;	}	pagesize = dbp->pgsize;	re_len = ((QUEUE *)dbp->q_internal)->re_len;	recs = ((QUEUE *)dbp->q_internal)->rec_page;	metapno = ((QUEUE *)dbp->q_internal)->q_meta;	is_key = LF_ISSET(DB_MULTIPLE_KEY) ? 1 : 0;	size = 0;	if ((ret = __db_lget(dbc, 0, metapno, DB_LOCK_READ, 0, &metalock)) != 0)		return (ret);	if ((ret = __memp_fget(mpf, &metapno, 0, &meta)) != 0) {		/* We did not fetch it, we can release the lock. */		(void)__LPUT(dbc, metalock);		return (ret);	}	dbuf = data->data;	np = dp = dbuf;	/* Keep track of space that is left.  There is an termination entry */	space = data->ulen;	space -= sizeof(*offp);	/* Build the offset/size table form the end up. */	endp = (int32_t *) ((u_int8_t *)dbuf + data->ulen);	endp--;	offp = endp;	/* Save the lock on the current position of the cursor. */	rlock = cp->lock;	LOCK_INIT(cp->lock);next_pg:	/* Wrap around, skipping zero. */	if (cp->recno == RECNO_OOB)		cp->recno++;	if ((ret = __qam_position(dbc, &cp->recno, mode, &exact)) != 0)		goto done;	pg = cp->page;	indx = cp->indx;	need_pg = 1;	do {		/*		 * If this page is a nonexistent page at the end of an		 * extent, pg may be NULL.  A NULL page has no valid records,		 * so just keep looping as though qp exists and isn't QAM_VALID;		 * calling QAM_GET_RECORD is unsafe.		 */		valid = 0;		if (pg != NULL) {			if ((ret = __db_lget(dbc, LCK_COUPLE,			     cp->recno, lkmode, DB_LOCK_RECORD, &rlock)) != 0)				goto done;			qp = QAM_GET_RECORD(dbp, pg, indx);			if (F_ISSET(qp, QAM_VALID)) {				valid = 1;				space -= (is_key ? 3 : 2) * sizeof(*offp);				if (space < 0)					goto get_space;				if (need_pg) {					dp = np;					size = pagesize - QPAGE_SZ(dbp);					if (space < size) {get_space:						if (offp == endp) {							data->size = (u_int32_t)							    DB_ALIGN(size +							    pagesize,							    sizeof(u_int32_t));							ret = DB_BUFFER_SMALL;							break;						}						if (indx != 0)							indx--;						cp->recno--;						space = 0;						break;					}					memcpy(dp,					    (char *)pg + QPAGE_SZ(dbp), size);					need_pg = 0;					space -= size;					np += size;				}				if (is_key)					*offp-- = cp->recno;				*offp-- = (int32_t)((u_int8_t*)qp -				    (u_int8_t*)pg - QPAGE_SZ(dbp) +				    dp - dbuf + SSZA(QAMDATA, data));				*offp-- = re_len;			}		}		if (!valid && is_key == 0) {			*offp-- = 0;			*offp-- = 0;		}		cp->recno++;	} while (++indx < recs && cp->recno != RECNO_OOB &&	    cp->recno != meta->cur_recno &&	    !QAM_AFTER_CURRENT(meta, cp->recno));	/* Drop the page lock. */	if ((t_ret = __LPUT(dbc, cp->lock)) != 0 && ret == 0)		ret = t_ret;	if (cp->page != NULL) {		if ((t_ret =		    __qam_fput(dbp, cp->pgno, cp->page, 0)) != 0 && ret == 0)			ret = t_ret;		cp->page = NULL;	}	if (ret == 0 && space > 0 &&	    (indx >= recs || cp->recno == RECNO_OOB) &&	    cp->recno != meta->cur_recno &&	    !QAM_AFTER_CURRENT(meta, cp->recno))		goto next_pg;	/*	 * Correct recno in two cases:	 * 1) If we just wrapped fetch must start at record 1 not a FIRST.	 * 2) We ran out of space exactly at the end of a page.	 */	if (cp->recno == RECNO_OOB || (space == 0 && indx == recs))		cp->recno--;	if (is_key == 1)		*offp = RECNO_OOB;	else		*offp = -1;done:	/* Release the meta page. */	if ((t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0)		ret = t_ret;	if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0)		ret = t_ret;	cp->lock = rlock;	return (ret);}/* * __qam_c_close -- *	Close down the cursor from a single use. */static int__qam_c_close(dbc, root_pgno, rmroot)	DBC *dbc;	db_pgno_t root_pgno;	int *rmroot;{	QUEUE_CURSOR *cp;	int ret;	COMPQUIET(root_pgno, 0);	COMPQUIET(rmroot, NULL);	cp = (QUEUE_CURSOR *)dbc->internal;	/* Discard any locks not acquired inside of a transaction. */	ret = __TLPUT(dbc, cp->lock);	LOCK_INIT(cp->lock);	cp->page = NULL;	cp->pgno = PGNO_INVALID;	cp->indx = 0;	cp->lock_mode = DB_LOCK_NG;	cp->recno = RECNO_OOB;	cp->flags = 0;	return (ret);}/* * __qam_c_dup -- *	Duplicate a queue cursor, such that the new one holds appropriate *	locks for the position of the original. * * PUBLIC: int __qam_c_dup __P((DBC *, DBC *)); */int__qam_c_dup(orig_dbc, new_dbc)	DBC *orig_dbc, *new_dbc;{	QUEUE_CURSOR *orig, *new;	int ret;	orig = (QUEUE_CURSOR *)orig_dbc->internal;	new = (QUEUE_CURSOR *)new_dbc->internal;	new->recno = orig->recno;	/* Acquire the long term lock if we are not in a transaction. */	if (orig_dbc->txn == NULL && LOCK_ISSET(orig->lock))		if ((ret = __db_lget(new_dbc, 0, new->recno,		    new->lock_mode, DB_LOCK_RECORD, &new->lock)) != 0)			return (ret);	return (0);}/* * __qam_c_init * * PUBLIC: int __qam_c_init __P((DBC *)); */int__qam_c_init(dbc)	DBC *dbc;{	QUEUE_CURSOR *cp;	DB *dbp;	int ret;	dbp = dbc->dbp;	/* Allocate the internal structure. */	cp = (QUEUE_CURSOR *)dbc->internal;	if (cp == NULL) {		if ((ret =		    __os_calloc(dbp->dbenv, 1, sizeof(QUEUE_CURSOR), &cp)) != 0)			return (ret);		dbc->internal = (DBC_INTERNAL *)cp;	}	/* Initialize methods. */	dbc->c_close = __db_c_close;	dbc->c_count = __db_c_count_pp;	dbc->c_del = __db_c_del_pp;	dbc->c_dup = __db_c_dup_pp;	dbc->c_get = __db_c_get_pp;	dbc->c_pget = __db_c_pget_pp;	dbc->c_put = __db_c_put_pp;	dbc->c_am_bulk = __qam_bulk;	dbc->c_am_close = __qam_c_close;	dbc->c_am_del = __qam_c_del;	dbc->c_am_destroy = __qam_c_destroy;	dbc->c_am_get = __qam_c_get;	dbc->c_am_put = __qam_c_put;	dbc->c_am_writelock = NULL;	return (0);}/* * __qam_c_destroy -- *	Close a single cursor -- internal version. */static int__qam_c_destroy(dbc)	DBC *dbc;{	/* Discard the structures. */	__os_free(dbc->dbp->dbenv, dbc->internal);	return (0);}/* * __qam_getno -- *	Check the user's record number. */static int__qam_getno(dbp, key, rep)	DB *dbp;	const DBT *key;	db_recno_t *rep;{	if ((*rep = *(db_recno_t *)key->data) == 0) {		__db_err(dbp->dbenv, "illegal record number of 0");		return (EINVAL);	}	return (0);}/* * __qam_truncate -- *	Truncate a queue database * * PUBLIC: int __qam_truncate __P((DBC *, u_int32_t *)); */int__qam_truncate(dbc, countp)	DBC *dbc;	u_int32_t *countp;{	DB *dbp;	DB_LOCK metalock;	DB_MPOOLFILE *mpf;	QMETA *meta;	db_pgno_t metapno;	u_int32_t count;	int ret, t_ret;	dbp = dbc->dbp;	/* Walk the queue, counting rows. */	for (count = 0;	    (ret = __qam_c_get(dbc, NULL, NULL, DB_CONSUME, &metapno)) == 0;)		count++;	if (ret != DB_NOTFOUND)		return (ret);	/* Update the meta page. */	metapno = ((QUEUE *)dbp->q_internal)->q_meta;	if ((ret =	    __db_lget(dbc, 0, metapno, DB_LOCK_WRITE, 0, &metalock)) != 0)		return (ret);	mpf = dbp->mpf;	if ((ret = __memp_fget(mpf, &metapno, 0, &meta)) != 0) {		/* We did not fetch it, we can release the lock. */		(void)__LPUT(dbc, metalock);		return (ret);	}	/* Remove the last extent file. */	if (meta->cur_recno > 1 && ((QUEUE *)dbp->q_internal)->page_ext != 0) {		if ((ret = __qam_fremove(dbp,		     QAM_RECNO_PAGE(dbp, meta->cur_recno - 1))) != 0)			return (ret);	}	if (DBC_LOGGING(dbc)) {		ret = __qam_mvptr_log(dbp, dbc->txn, &meta->dbmeta.lsn, 0,		    QAM_SETCUR | QAM_SETFIRST | QAM_TRUNCATE, meta->first_recno,		    1, meta->cur_recno, 1, &meta->dbmeta.lsn, PGNO_BASE_MD);	}	if (ret == 0)		meta->first_recno = meta->cur_recno = 1;	if ((t_ret = __memp_fput(mpf,	    meta, ret == 0 ? DB_MPOOL_DIRTY: 0)) != 0 && ret == 0)		ret = t_ret;	if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0)		ret = t_ret;	*countp = count;	return (ret);}

⌨️ 快捷键说明

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