btlock.cpp

来自「CBASE v1.01 采用Borland公司TC++编写的数据库管理源程序库」· C++ 代码 · 共 206 行

CPP
206
字号
/*	Copyright (c) 1989 Citadel	*/
/*	   All Rights Reserved    	*/

/* #ident	"@(#)btlock.c	1.4 - 90/06/20" */

#include <blkio.h>
#include <errno.h>

/* local headers */
#include "btree_.h"

/* function declarations */
#ifdef AC_HDRS
int resync(btree_t *btp);
#else
int resync();
#endif

/*man---------------------------------------------------------------------------
NAME
     btlock - btree lock

SYNOPSIS
     #include <btree.h>

     int btlock(btp, ltype)
     btree_t *btp;
     int ltype;

DESCRIPTION
     The btlock function controls the lock status of a btree.  The btp
     argument is an open btree.  ltype indicates the target status of
     the lock on the btree.

     The lock types available are:

          BT_UNLCK - unlock btree
          BT_RDLCK - lock btree for reading
          BT_WRLCK - lock btree for reading and writing
          BT_RDLKW - lock btree for reading (wait)
          BT_WRLKW - lock btree for reading and writing (wait)

     For the lock types which wait, btlock will not return until the
     lock is available.  For the lock types which do not wait, if
     the lock is unavailable because of a lock held by another process
     a value of -1 is returned and errno set to EAGAIN.

     When a btree is unlocked, its cursor is set to null.

     The buffers are flushed before unlocking.

     btlock will fail if one or more of the following is true:

     [EAGAIN]       ltype is BT_RDLCK and btp is already write locked
                    by another process, or ltype is BT_WRLCK and btp
                    is already read or write locked by another
                    process.
     [EINVAL]       btp is is not a valid btree pointer.
     [EINVAL]       ltype is not one of the valid lock types.
     [BTECORRUPT]   btp is corrupt.
     [BTENOPEN]     btp is not open.
     [BTENOPEN]     ltype is BT_RDLCK or BT_RDLKW and btp is not
                    opened for reading or ltype is BT_WRLCK or
                    BT_WRLKW and btp is not open for writing.

SEE ALSO
     btgetlck.

DIAGNOSTICS
     Upon successful completion, a value of 0 is returned.  Otherwise,
     a value of -1 is returned, and errno set to indicate the error.

------------------------------------------------------------------------------*/
int btlock(btree_t *btp, int ltype)
{
	int bltype = 0;		/* blkio lock type */

	/* validate arguments */
	if (!bt_valid(btp)) {
		errno = EINVAL;
		return -1;
	}

	/* check if btree not open */
	if (!(btp->flags & BTOPEN)) {
		errno = BTENOPEN;
		return -1;
	}

	/* check if btree not open for lock ltype */
	switch (ltype) {
	case BT_UNLCK:
		btp->cbtpos.node = NIL;		/* set cursor to null */
		btp->cbtpos.key = 0;
		bltype = B_UNLCK;
		break;
	case BT_RDLCK:
		if (!(btp->flags & BTREAD)) {
			errno = BTENOPEN;
			return -1;
		}
		bltype = B_RDLCK;
		break;
	case BT_RDLKW:
		if (!(btp->flags & BTREAD)) {
			errno = BTENOPEN;
			return -1;
		}
		bltype = B_RDLKW;
		break;
	case BT_WRLCK:
		if (!(btp->flags & BTWRITE)) {
			errno = BTENOPEN;
			return -1;
		}
		bltype = B_WRLCK;
		break;
	case BT_WRLKW:
		if (!(btp->flags & BTWRITE)) {
			errno = BTENOPEN;
			return -1;
		}
		bltype = B_WRLKW;
		break;
	default:
		errno = EINVAL;
		return -1;
		break;
	}

	/* lock btree file */
	if (lockb(btp->bp, bltype, (bpos_t)0, (bpos_t)0) == -1) {
		if (errno != EAGAIN) BTEPRINT;
		return -1;
	}

	/* set status bits in btree control structure */
	switch (ltype) {
	case BT_UNLCK:
		btp->flags &= ~BTLOCKS;
		break;
	case BT_RDLCK:
	case BT_RDLKW:
		/* if previously unlocked, re-sync with file */
		if (!(btp->flags & BTLOCKS)) {
			if (resync(btp) == -1) {
				BTEPRINT;
				return -1;
			}
		}
		btp->flags |= BTRDLCK;
		btp->flags &= ~BTWRLCK;
		break;
	case BT_WRLCK:
	case BT_WRLKW:
		/* if previously unlocked, re-sync with file */
		if (!(btp->flags & BTLOCKS)) {
			if (resync(btp) == -1) {
				BTEPRINT;
				return -1;
			}
		}
		btp->flags |= (BTRDLCK | BTWRLCK);
		break;
	default:
		BTEPRINT;
		errno = BTEPANIC;
		return -1;
		break;
	}

	errno = 0;
	return 0;
}

/* resync:  re-sync with file */
int resync(btree_t *btp)
{
	unsigned long	oldheight	= 0;
	btpos_t	*	sp		= NULL;

	oldheight = btp->bthdr.height;
	if (bgeth(btp->bp, &btp->bthdr) == -1) {
		BTEPRINT;
		return -1;
	}
	if (btp->bthdr.flags & BTHMOD) {
		errno = BTECORRUPT;
		return -1;
	}
	if (btp->bthdr.height != oldheight) {
		sp = (btpos_t *)realloc(btp->sp, (size_t)(btp->bthdr.height + 1) * sizeof(*sp));
		if (sp == NULL) {
			BTEPRINT;
			errno = ENOMEM;
			return -1;
		}
		btp->sp = sp;
		sp = NULL;
		btp->sp[btp->bthdr.height].node = NIL;
		btp->sp[btp->bthdr.height].key = 0;
	}

	return 0;
}

⌨️ 快捷键说明

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