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

📄 env_region.c

📁 这是国外的resip协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
			lastrm = cnt;			continue;		}		/* Remove the file. */		if (__db_appname(dbenv,		    DB_APP_NONE, names[cnt], 0, NULL, &path) == 0) {			/*			 * Overwrite region files.  Temporary files would have			 * been maintained in encrypted format, so there's no			 * reason to overwrite them.  This is not an exact			 * check on the file being a region file, but it's			 * not likely to be wrong, and the worst thing that can			 * happen is we overwrite a file that didn't need to be			 * overwritten.			 */			if (F_ISSET(dbenv, DB_ENV_OVERWRITE) &&			    strlen(names[cnt]) == DB_REGION_NAME_LENGTH)				(void)__db_overwrite(dbenv, path);			(void)__os_unlink(dbenv, path);			__os_free(dbenv, path);		}	}	if (lastrm != -1)		if (__db_appname(dbenv,		    DB_APP_NONE, names[lastrm], 0, NULL, &path) == 0) {			if (F_ISSET(dbenv, DB_ENV_OVERWRITE))				(void)__db_overwrite(dbenv, path);			(void)__os_unlink(dbenv, path);			__os_free(dbenv, path);		}	__os_dirfree(dbenv, names, fcnt);	return (0);}/* * __db_r_attach *	Join/create a region. * * PUBLIC: int __db_r_attach __P((DB_ENV *, REGINFO *, size_t)); */int__db_r_attach(dbenv, infop, size)	DB_ENV *dbenv;	REGINFO *infop;	size_t size;{	REGENV *renv;	REGION *rp;	int ret;	char buf[sizeof(DB_REGION_FMT) + 20];	renv = ((REGINFO *)dbenv->reginfo)->primary;	/* Lock the environment. */	MUTEX_LOCK(dbenv, &renv->mutex);	/*	 * Find or create a REGION structure for this region.  If we create	 * it, the REGION_CREATE flag will be set in the infop structure.	 */	F_CLR(infop, REGION_CREATE);	if ((ret = __db_des_get(dbenv, dbenv->reginfo, infop, &rp)) != 0) {		MUTEX_UNLOCK(dbenv, &renv->mutex);		return (ret);	}	infop->dbenv = dbenv;	infop->rp = rp;	infop->type = rp->type;	infop->id = rp->id;	/* If we're creating the region, set the desired size. */	if (F_ISSET(infop, REGION_CREATE))		rp->size = (roff_t)size;	/* Join/create the underlying region. */	(void)snprintf(buf, sizeof(buf), DB_REGION_FMT, infop->id);	if ((ret = __db_appname(dbenv,	    DB_APP_NONE, buf, 0, NULL, &infop->name)) != 0)		goto err;	if ((ret = __os_r_attach(dbenv, infop, rp)) != 0)		goto err;	/*	 * Fault the pages into memory.  Note, do this BEFORE we initialize	 * anything because we're writing pages in created regions, not just	 * reading them.	 */	(void)__db_faultmem(dbenv,	    infop->addr, rp->size, F_ISSET(infop, REGION_CREATE));	/*	 * !!!	 * The underlying layer may have just decided that we are going	 * to create the region.  There are various system issues that	 * can result in a useless region that requires re-initialization.	 *	 * If we created the region, initialize it for allocation.	 */	if (F_ISSET(infop, REGION_CREATE))		__db_shalloc_init(infop, rp->size);	/*	 * If the underlying REGION isn't the environment, acquire a lock	 * for it and release our lock on the environment.	 */	if (infop->type != REGION_TYPE_ENV) {		MUTEX_LOCK(dbenv, &rp->mutex);		MUTEX_UNLOCK(dbenv, &renv->mutex);	}	return (0);err:	/* Discard the underlying region. */	if (infop->addr != NULL)		(void)__os_r_detach(dbenv,		    infop, F_ISSET(infop, REGION_CREATE));	infop->rp = NULL;	infop->id = INVALID_REGION_ID;	/* Discard the REGION structure if we created it. */	if (F_ISSET(infop, REGION_CREATE)) {		(void)__db_des_destroy(dbenv, rp, 1);		F_CLR(infop, REGION_CREATE);	}	/* Release the environment lock. */	MUTEX_UNLOCK(dbenv, &renv->mutex);	return (ret);}/* * __db_r_detach -- *	Detach from a region. * * PUBLIC: int __db_r_detach __P((DB_ENV *, REGINFO *, int)); */int__db_r_detach(dbenv, infop, destroy)	DB_ENV *dbenv;	REGINFO *infop;	int destroy;{	REGENV *renv;	REGION *rp;	int ret, t_ret;	renv = ((REGINFO *)dbenv->reginfo)->primary;	rp = infop->rp;	if (F_ISSET(dbenv, DB_ENV_PRIVATE))		destroy = 1;	/* Lock the environment. */	MUTEX_LOCK(dbenv, &renv->mutex);	/* Acquire the lock for the REGION. */	MUTEX_LOCK(dbenv, &rp->mutex);	/*	 * We need to call destroy on per-subsystem info before we free the	 * memory associated with the region.	 */	if (destroy)		__db_region_destroy(dbenv, infop);	/* Detach from the underlying OS region. */	ret = __os_r_detach(dbenv, infop, destroy);	/* Release the REGION lock. */	MUTEX_UNLOCK(dbenv, &rp->mutex);	/*	 * If we destroyed the region, discard the REGION structure.  The only	 * time this routine is called with the destroy flag set is when the	 * environment is being removed, and it's likely that the only reason	 * the environment is being removed is because we crashed.  Don't do	 * any unnecessary shared memory manipulation.	 */	if (destroy &&	    ((t_ret = __db_des_destroy(		dbenv, rp, F_ISSET(dbenv, DB_ENV_PRIVATE))) != 0) && ret == 0)		ret = t_ret;	/* Release the environment lock. */	MUTEX_UNLOCK(dbenv, &renv->mutex);	/* Destroy the structure. */	if (infop->name != NULL)		__os_free(dbenv, infop->name);	return (ret);}/* * __db_des_get -- *	Return a reference to the shared information for a REGION, *	optionally creating a new entry. */static int__db_des_get(dbenv, env_infop, infop, rpp)	DB_ENV *dbenv;	REGINFO *env_infop, *infop;	REGION **rpp;{	REGENV *renv;	REGION *rp, *first_type;	u_int32_t maxid;	int ret;	/*	 * !!!	 * Called with the environment already locked.	 */	*rpp = NULL;	renv = env_infop->primary;	/*	 * If the caller wants to join a region, walk through the existing	 * regions looking for a matching ID (if ID specified) or matching	 * type (if type specified).  If we return based on a matching type	 * return the "primary" region, that is, the first region that was	 * created of this type.	 *	 * Track the maximum region ID so we can allocate a new region,	 * note that we have to start at 1 because the primary environment	 * uses ID == 1.	 */	maxid = REGION_ID_ENV;	for (first_type = NULL,	    rp = SH_LIST_FIRST(&renv->regionq, __db_region);	    rp != NULL; rp = SH_LIST_NEXT(rp, q, __db_region)) {		if (infop->id != INVALID_REGION_ID) {			if (infop->id == rp->id)				break;			continue;		}		if (infop->type == rp->type &&		    F_ISSET(infop, REGION_JOIN_OK) &&		    (first_type == NULL || first_type->id > rp->id))			first_type = rp;		if (rp->id > maxid)			maxid = rp->id;	}	if (rp == NULL)		rp = first_type;	/*	 * If we didn't find a region and we can't create the region, fail.	 * The caller generates any error message.	 */	if (rp == NULL && !F_ISSET(infop, REGION_CREATE_OK))		return (ENOENT);	/*	 * If we didn't find a region, create and initialize a REGION structure	 * for the caller.  If id was set, use that value, otherwise we use the	 * next available ID.	 */	if (rp == NULL) {		if ((ret = __db_shalloc(env_infop,		    sizeof(REGION), MUTEX_ALIGN, &rp)) != 0) {			__db_err(dbenv,			    "unable to create new master region entry: %s",			    db_strerror(ret));			return (ret);		}		/* Initialize the region. */		memset(rp, 0, sizeof(*rp));		if ((ret = __db_mutex_setup(dbenv, env_infop, &rp->mutex,		    MUTEX_NO_RECORD | MUTEX_NO_RLOCK)) != 0) {			__db_shalloc_free(env_infop, rp);			return (ret);		}		rp->segid = INVALID_REGION_SEGID;		/*		 * Set the type and ID; if no region ID was specified,		 * allocate one.		 */		rp->type = infop->type;		rp->id = infop->id == INVALID_REGION_ID ? maxid + 1 : infop->id;		SH_LIST_INSERT_HEAD(&renv->regionq, rp, q, __db_region);		F_SET(infop, REGION_CREATE);	}	*rpp = rp;	return (0);}/* * __db_des_destroy -- *	Destroy a reference to a REGION. */static int__db_des_destroy(dbenv, rp, shmem_safe)	DB_ENV *dbenv;	REGION *rp;	int shmem_safe;{	REGINFO *infop;	/*	 * !!!	 * Called with the environment already locked.	 */	infop = dbenv->reginfo;	/*	 * If we're calling during recovery, it may not be safe to access the	 * shared memory, as the shared memory may have been corrupted during	 * the crash.  If the shared memory is safe, remove the REGION entry	 * from its linked list, destroy the mutex, and free the allocated	 * memory.  On systems that require system mutex support, we don't	 * have a choice -- safe or not, we have to destroy the mutex or we'll	 * leak memory.	 */#ifdef HAVE_MUTEX_SYSTEM_RESOURCES	(void)__db_mutex_destroy(&rp->mutex);#else	if (shmem_safe)		(void)__db_mutex_destroy(&rp->mutex);#endif	if (shmem_safe) {		SH_LIST_REMOVE(rp, q, __db_region);		__db_shalloc_free(infop, rp);	}	return (0);}/* * __db_faultmem -- *	Fault the region into memory. */static int__db_faultmem(dbenv, addr, size, created)	DB_ENV *dbenv;	void *addr;	size_t size;	int created;{	int ret;	u_int8_t *p, *t;	/* Ignore heap regions. */	if (F_ISSET(dbenv, DB_ENV_PRIVATE))		return (0);	/*	 * It's sometimes significantly faster to page-fault in all of the	 * region's pages before we run the application, as we see nasty	 * side-effects when we page-fault while holding various locks, i.e.,	 * the lock takes a long time to acquire because of the underlying	 * page fault, and the other threads convoy behind the lock holder.	 *	 * If we created the region, we write a non-zero value so that the	 * system can't cheat.  If we're just joining the region, we can	 * only read the value and try to confuse the compiler sufficiently	 * that it doesn't figure out that we're never really using it.	 */	ret = 0;	if (F_ISSET(dbenv, DB_ENV_REGION_INIT)) {		if (created)			for (p = addr, t = (u_int8_t *)addr + size;			    p < t; p += OS_VMPAGESIZE)				p[0] = 0xdb;		else			for (p = addr, t = (u_int8_t *)addr + size;			    p < t; p += OS_VMPAGESIZE)				ret |= p[0];	}	return (ret);}/* * __db_region_destroy -- *	Destroy per-subsystem region information. *	Called with the region already locked. */static void__db_region_destroy(dbenv, infop)	DB_ENV *dbenv;	REGINFO *infop;{	switch (infop->type) {	case REGION_TYPE_LOCK:		__lock_region_destroy(dbenv, infop);		break;	case REGION_TYPE_LOG:		__log_region_destroy(dbenv, infop);		break;	case REGION_TYPE_MPOOL:		__memp_region_destroy(dbenv, infop);		break;	case REGION_TYPE_TXN:		__txn_region_destroy(dbenv, infop);		break;	case REGION_TYPE_ENV:	case REGION_TYPE_MUTEX:		break;	case INVALID_REGION_TYPE:	default:		DB_ASSERT(0);		break;	}}

⌨️ 快捷键说明

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