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

📄 lock.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 4 页
字号:
	LOCKREGION(dbenv, lt);	ret = __lock_put_nolock(dbenv, lock, &run_dd, 0);	UNLOCKREGION(dbenv, lt);	/*	 * Only run the lock detector if put told us to AND we are running	 * in auto-detect mode.  If we are not running in auto-detect, then	 * a call to lock_detect here will 0 the need_dd bit, but will not	 * actually abort anything.	 */	if (ret == 0 && run_dd)		(void)dbenv->lock_detect(dbenv, 0,		    ((DB_LOCKREGION *)lt->reginfo.primary)->detect, NULL);	return (ret);}static int__lock_put_nolock(dbenv, lock, runp, flags)	DB_ENV *dbenv;	DB_LOCK *lock;	int *runp;	u_int32_t flags;{	struct __db_lock *lockp;	DB_LOCKREGION *region;	DB_LOCKTAB *lt;	int ret;	/* Check if locks have been globally turned off. */	if (F_ISSET(dbenv, DB_ENV_NOLOCKING))		return (0);	lt = dbenv->lk_handle;	region = lt->reginfo.primary;	lockp = (struct __db_lock *)R_ADDR(&lt->reginfo, lock->off);	LOCK_INIT(*lock);	if (lock->gen != lockp->gen) {		__db_err(dbenv, __db_lock_invalid, "DB_LOCK->lock_put");		return (EINVAL);	}	ret = __lock_put_internal(lt,	    lockp, lock->ndx, flags | DB_LOCK_UNLINK | DB_LOCK_FREE);	*runp = 0;	if (ret == 0 && region->need_dd && region->detect != DB_LOCK_NORUN)		*runp = 1;	return (ret);}/* * __lock_downgrade -- *	Used to downgrade locks.  Currently this is used in two places, * 1) by the concurrent access product to downgrade write locks * back to iwrite locks and 2) to downgrade write-handle locks to read-handle * locks at the end of an open/create. * * PUBLIC: int __lock_downgrade __P((DB_ENV *, * PUBLIC:     DB_LOCK *, db_lockmode_t, u_int32_t)); */int__lock_downgrade(dbenv, lock, new_mode, flags)	DB_ENV *dbenv;	DB_LOCK *lock;	db_lockmode_t new_mode;	u_int32_t flags;{	struct __db_lock *lockp;	DB_LOCKER *sh_locker;	DB_LOCKOBJ *obj;	DB_LOCKREGION *region;	DB_LOCKTAB *lt;	u_int32_t indx;	int ret;	COMPQUIET(flags, 0);	PANIC_CHECK(dbenv);	ret = 0;	/* Check if locks have been globally turned off. */	if (F_ISSET(dbenv, DB_ENV_NOLOCKING))		return (0);	lt = dbenv->lk_handle;	region = lt->reginfo.primary;	LOCKREGION(dbenv, lt);	lockp = (struct __db_lock *)R_ADDR(&lt->reginfo, lock->off);	if (lock->gen != lockp->gen) {		__db_err(dbenv, __db_lock_invalid, "lock_downgrade");		ret = EINVAL;		goto out;	}	LOCKER_LOCK(lt, region, lockp->holder, indx);	if ((ret = __lock_getlocker(lt, lockp->holder,	    indx, 0, &sh_locker)) != 0 || sh_locker == NULL) {		if (ret == 0)			ret = EINVAL;		__db_err(dbenv, __db_locker_invalid);		goto out;	}	if (IS_WRITELOCK(lockp->mode) && !IS_WRITELOCK(new_mode))		sh_locker->nwrites--;	if (new_mode == DB_LOCK_WWRITE)		F_SET(sh_locker, DB_LOCKER_DIRTY);	lockp->mode = new_mode;	/* Get the object associated with this lock. */	obj = (DB_LOCKOBJ *)((u_int8_t *)lockp + lockp->obj);	(void)__lock_promote(lt, obj, LF_ISSET(DB_LOCK_NOWAITERS));out:	UNLOCKREGION(dbenv, lt);	return (ret);}static int__lock_put_internal(lt, lockp, obj_ndx, flags)	DB_LOCKTAB *lt;	struct __db_lock *lockp;	u_int32_t obj_ndx, flags;{	DB_LOCKOBJ *sh_obj;	DB_LOCKREGION *region;	int ret, state_changed;	region = lt->reginfo.primary;	ret = state_changed = 0;	if (!OBJ_LINKS_VALID(lockp)) {		/*		 * Someone removed this lock while we were doing a release		 * by locker id.  We are trying to free this lock, but it's		 * already been done; all we need to do is return it to the		 * free list.		 */		lockp->status = DB_LSTAT_FREE;		SH_TAILQ_INSERT_HEAD(		    &region->free_locks, lockp, links, __db_lock);		region->stat.st_nlocks--;		return (0);	}	if (LF_ISSET(DB_LOCK_DOALL))		region->stat.st_nreleases += lockp->refcount;	else		region->stat.st_nreleases++;	if (!LF_ISSET(DB_LOCK_DOALL) && lockp->refcount > 1) {		lockp->refcount--;		return (0);	}	/* Increment generation number. */	lockp->gen++;	/* Get the object associated with this lock. */	sh_obj = (DB_LOCKOBJ *)((u_int8_t *)lockp + lockp->obj);	/* Remove this lock from its holders/waitlist. */	if (lockp->status != DB_LSTAT_HELD && lockp->status != DB_LSTAT_PENDING)		__lock_remove_waiter(lt, sh_obj, lockp, DB_LSTAT_FREE);	else {		SH_TAILQ_REMOVE(&sh_obj->holders, lockp, links, __db_lock);		lockp->links.stqe_prev = -1;	}	if (LF_ISSET(DB_LOCK_NOPROMOTE))		state_changed = 0;	else		state_changed = __lock_promote(lt,		    sh_obj, LF_ISSET(DB_LOCK_REMOVE | DB_LOCK_NOWAITERS));	if (LF_ISSET(DB_LOCK_UNLINK))		ret = __lock_checklocker(lt, lockp, lockp->holder, flags);	/* Check if object should be reclaimed. */	if (SH_TAILQ_FIRST(&sh_obj->holders, __db_lock) == NULL &&	    SH_TAILQ_FIRST(&sh_obj->waiters, __db_lock) == NULL) {		HASHREMOVE_EL(lt->obj_tab,		    obj_ndx, __db_lockobj, links, sh_obj);		if (sh_obj->lockobj.size > sizeof(sh_obj->objdata))			__db_shalloc_free(lt->reginfo.addr,			    SH_DBT_PTR(&sh_obj->lockobj));		SH_TAILQ_INSERT_HEAD(		    &region->free_objs, sh_obj, links, __db_lockobj);		region->stat.st_nobjects--;		state_changed = 1;	}	/* Free lock. */	if (!LF_ISSET(DB_LOCK_UNLINK) && LF_ISSET(DB_LOCK_FREE)) {		lockp->status = DB_LSTAT_FREE;		SH_TAILQ_INSERT_HEAD(		    &region->free_locks, lockp, links, __db_lock);		region->stat.st_nlocks--;	}	/*	 * If we did not promote anyone; we need to run the deadlock	 * detector again.	 */	if (state_changed == 0)		region->need_dd = 1;	return (ret);}/* * Utility functions; listed alphabetically. *//* * __lock_checklocker -- *	If a locker has no more locks, then we can free the object. * Return a boolean indicating whether we freed the object or not. * * Must be called without the locker's lock set. */static int__lock_checklocker(lt, lockp, locker, flags)	DB_LOCKTAB *lt;	struct __db_lock *lockp;	u_int32_t locker, flags;{	DB_ENV *dbenv;	DB_LOCKER *sh_locker;	DB_LOCKREGION *region;	u_int32_t indx;	int ret;	dbenv = lt->dbenv;	region = lt->reginfo.primary;	ret = 0;	LOCKER_LOCK(lt, region, locker, indx);	/* If the locker's list is NULL, free up the locker. */	if ((ret = __lock_getlocker(lt,	    locker, indx, 0, &sh_locker)) != 0 || sh_locker == NULL) {		if (ret == 0)			ret = EINVAL;		__db_err(dbenv, __db_locker_invalid);		goto freelock;	}	if (F_ISSET(sh_locker, DB_LOCKER_DELETED)) {		LF_CLR(DB_LOCK_FREE);		if (!LF_ISSET(DB_LOCK_IGNOREDEL))			goto freelock;	}	if (LF_ISSET(DB_LOCK_UNLINK)) {		SH_LIST_REMOVE(lockp, locker_links, __db_lock);		if (lockp->status == DB_LSTAT_HELD) {			sh_locker->nlocks--;			if (IS_WRITELOCK(lockp->mode))				sh_locker->nwrites--;		}	}	if (SH_LIST_FIRST(&sh_locker->heldby, __db_lock) == NULL &&	    LF_ISSET(DB_LOCK_FREE_LOCKER))		__lock_freelocker( lt, region, sh_locker, indx);freelock:	if (LF_ISSET(DB_LOCK_FREE)) {		lockp->status = DB_LSTAT_FREE;		SH_TAILQ_INSERT_HEAD(		    &region->free_locks, lockp, links, __db_lock);		region->stat.st_nlocks--;	}	return (ret);}/* * __lock_addfamilylocker *	Put a locker entry in for a child transaction. * * PUBLIC: int __lock_addfamilylocker __P((DB_ENV *, u_int32_t, u_int32_t)); */int__lock_addfamilylocker(dbenv, pid, id)	DB_ENV *dbenv;	u_int32_t pid, id;{	DB_LOCKER *lockerp, *mlockerp;	DB_LOCKREGION *region;	DB_LOCKTAB *lt;	u_int32_t ndx;	int ret;	lt = dbenv->lk_handle;	region = lt->reginfo.primary;	LOCKREGION(dbenv, lt);	/* get/create the  parent locker info */	LOCKER_LOCK(lt, region, pid, ndx);	if ((ret = __lock_getlocker(dbenv->lk_handle,	    pid, ndx, 1, &mlockerp)) != 0)		goto err;	/*	 * We assume that only one thread can manipulate	 * a single transaction family.	 * Therefore the master locker cannot go away while	 * we manipulate it, nor can another child in the	 * family be created at the same time.	 */	LOCKER_LOCK(lt, region, id, ndx);	if ((ret = __lock_getlocker(dbenv->lk_handle,	    id, ndx, 1, &lockerp)) != 0)		goto err;	/* Point to our parent. */	lockerp->parent_locker = R_OFFSET(&lt->reginfo, mlockerp);	/* See if this locker is the family master. */	if (mlockerp->master_locker == INVALID_ROFF)		lockerp->master_locker = R_OFFSET(&lt->reginfo, mlockerp);	else {		lockerp->master_locker = mlockerp->master_locker;		mlockerp = R_ADDR(&lt->reginfo, mlockerp->master_locker);	}	/*	 * Link the child at the head of the master's list.	 * The guess is when looking for deadlock that	 * the most recent child is the one thats blocked.	 */	SH_LIST_INSERT_HEAD(	    &mlockerp->child_locker, lockerp, child_link, __db_locker);err:	UNLOCKREGION(dbenv, lt);	return (ret);}/* * __lock_freefamilylocker *	Remove a locker from the hash table and its family. * * This must be called without the locker bucket locked. * * PUBLIC: int __lock_freefamilylocker  __P((DB_LOCKTAB *, u_int32_t)); */int__lock_freefamilylocker(lt, locker)	DB_LOCKTAB *lt;	u_int32_t locker;{	DB_ENV *dbenv;	DB_LOCKER *sh_locker;	DB_LOCKREGION *region;	u_int32_t indx;	int ret;	dbenv = lt->dbenv;	region = lt->reginfo.primary;	LOCKREGION(dbenv, lt);	LOCKER_LOCK(lt, region, locker, indx);	if ((ret = __lock_getlocker(lt,	    locker, indx, 0, &sh_locker)) != 0 || sh_locker == NULL)		goto freelock;	if (SH_LIST_FIRST(&sh_locker->heldby, __db_lock) != NULL) {		ret = EINVAL;		__db_err(dbenv, "Freeing locker with locks");		goto freelock;	}	/* If this is part of a family, we must fix up its links. */	if (sh_locker->master_locker != INVALID_ROFF)		SH_LIST_REMOVE(sh_locker, child_link, __db_locker);	__lock_freelocker(lt, region, sh_locker, indx);freelock:	UNLOCKREGION(dbenv, lt);	return (ret);}/* * __lock_freelocker *	common code for deleting a locker. * * This must be called with the locker bucket locked. */static void__lock_freelocker(lt, region, sh_locker, indx)	DB_LOCKTAB *lt;	DB_LOCKREGION *region;	DB_LOCKER *sh_locker;	u_int32_t indx;{	HASHREMOVE_EL(	    lt->locker_tab, indx, __db_locker, links, sh_locker);	SH_TAILQ_INSERT_HEAD(	    &region->free_lockers, sh_locker, links, __db_locker);	SH_TAILQ_REMOVE(&region->lockers, sh_locker, ulinks, __db_locker);	region->stat.st_nlockers--;}/* * __lock_set_timeout *		-- set timeout values in shared memory. * This is called from the transaction system. * We either set the time that this tranaction expires or the * amount of time that a lock for this transaction is permitted * to wait. * * PUBLIC: int __lock_set_timeout __P(( DB_ENV *, * PUBLIC:      u_int32_t, db_timeout_t, u_int32_t)); */int__lock_set_timeout(dbenv, locker, timeout, op)	DB_ENV *dbenv;	u_int32_t locker;	db_timeout_t timeout;	u_int32_t op;{	DB_LOCKER *sh_locker;	DB_LOCKREGION *region;	DB_LOCKTAB *lt;	u_int32_t locker_ndx;	int ret;	lt = dbenv->lk_handle;	region = lt->reginfo.primary;	LOCKREGION(dbenv, lt);	LOCKER_LOCK(lt, region, locker, locker_ndx);	ret = __lock_getlocker(lt, locker, locker_ndx, 1, &sh_locker);	UNLOCKREGION(dbenv, lt);	if (ret != 0)		return (ret);	if (op == DB_SET_TXN_TIMEOUT) {		if (timeout == 0)			LOCK_SET_TIME_INVALID(&sh_locker->tx_expire);		else			__lock_expires(dbenv, &sh_locker->tx_expire, timeout);	} else if (op == DB_SET_LOCK_TIMEOUT) {		sh_locker->lk_timeout = timeout;		F_SET(sh_locker, DB_LOCKER_TIMEOUT);	} else if (op == DB_SET_TXN_NOW) {		LOCK_SET_TIME_INVALID(&sh_locker->tx_expire);		__lock_expires(dbenv, &sh_locker->tx_expire, 0);		sh_locker->lk_expire = sh_locker->tx_expire;	} else		return (EINVAL);	return (0);}

⌨️ 快捷键说明

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