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

📄 lockrec.c

📁 T-kernel 的extension源代码
💻 C
字号:
/* *---------------------------------------------------------------------- *    T-Kernel / Standard Extension * *    Copyright (C) 2006 by Ken Sakamura. All rights reserved. *    T-Kernel / Standard Extension is distributed  *      under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * *    Version:   1.00.00 *    Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* *	lockrec.c (file) * *	File management *	Record lock */#include "fileio.h"LOCAL ER insertLockWaitQue( FmCmdPkt *pkt, RCB *rcb );LOCAL void removeLockWaitQue( RCB *rcb, FsInfo *fsinfo );LOCAL ER unlock( FD *fd, RCB *rcb );LOCAL WER lock( FD *fd, RCB *rcb );LOCAL ER testAndLock( FD *fd, RCB *rcb );LOCAL ER checkLock( FD *fd, RCB *rcb );/* * Register in the lock-waiting queue. *	Register them in the order of process priority. */LOCAL ER insertLockWaitQue( FmCmdPkt *pkt, RCB *rcb ){	QUEUE		*q;	W		pri, mypri;	ER		err;	mypri = GetProcessPriority(pkt->wrk.pinfo->procid);	if ( mypri < 0 ) {		err = mypri;		goto err_ret;	}	for ( q = rcb->lkwait.next; q != &rcb->lkwait; q = q->next ) {		PINFO	*pinfo = ((FmCmdPkt*)q)->wrk.pinfo;		pri = GetProcessPriority(pinfo->procid);		if ( pri < 0 ) {			err = pri;			goto err_ret;		}		if ( pri > mypri ) {			break;		}	}	QueInsert(&pkt->cmd.q, q);	return E_OK;err_ret:	DEBUG_PRINT(("insertLockWaitQue err = %d\n", err));	return err;}/* * Release the lock waiting. *	Fetch the first lock-waiting request of rcb, and resume processing. */LOCAL void removeLockWaitQue( RCB *rcb, FsInfo *fsinfo ){	FmCmdPkt	*waitReq;	/* Fetch the lock-waiting request. */	waitReq = (FmCmdPkt*)QueRemoveNext(&rcb->lkwait);	if ( waitReq != NULL ) {		/* Register in the queue of resume requests. */		QueInsert(&waitReq->cmd.q, &fsinfo->resumeReq);	}}/* * Release the lock. */LOCAL ER unlock( FD *fd, RCB *rcb ){	if ( isLockRecord(fd, rcb) ) {		/* It is not locked by itself. */		return E_LOCK;	}	/* Release the lock. */	rcb->lkfd = NULL;	/* Release the waiting of waiting request.  */	removeLockWaitQue(rcb, fd->ofcb->fsinfo);	return E_OK;}/* * Lock *	When going into lock waiting, return 1. Otherwise return 0. */LOCAL WER lock( FD *fd, RCB *rcb ){	BOOL	wait = FALSE;	if ( isLockRecord(fd, rcb) ) {		if ( rcb->lkfd->pinfo == fd->pinfo ) {			/* Locked from the same process. */			return E_LOCK;		}		/* Wait until the lock is released. */		wait = TRUE;	} else {		/* Lock */		rcb->lkfd = fd;	}	return wait;}/* * Test and Lock */LOCAL ER testAndLock( FD *fd, RCB *rcb ){	if ( isLockRecord(fd, rcb) ) {		return E_LOCK;	}	/* Lock */	rcb->lkfd = fd;	return E_OK;}/* * Check the lock state. */LOCAL ER checkLock( FD *fd, RCB *rcb ){	return isLockRecord(fd, rcb)? E_LOCK: E_OK;}/* * Record lock */EXPORT FwdID fmpLockRecord( FmCmdPkt *pkt ){	FM_LOC_REC_PARA	*cmdPara = (FM_LOC_REC_PARA*)pkt->cmd.para;	FD		*fd;	RCB		*rcb;	FwdID		fwd;	ER		err;	/* Obtain FD. */	fd = getFDp(cmdPara->fd);	/* Current record */	rcb = fd->crcb;	if ( isEndRCB(rcb, fd->ofcb) ) {		err = E_ENDR;		goto err_ret;	}	switch( cmdPara->mode ) {	  case F_UNLOCK:	/* Unlock */		err = unlock(fd, rcb);		break;	  case F_LOCK:		/* Lock */		err = lock(fd, rcb);		break;	  case F_TSLOCK:	/* Test and Lock */		err = testAndLock(fd, rcb);		break;	  case F_CKLOCK:	/* Check the lock state. */		err = checkLock(fd, rcb);		break;	  default:		err = E_PAR;		goto err_ret;	}	if ( (W)err > 0 ) {		/* Go into lock waiting. */		err = insertLockWaitQue(pkt, rcb);		if ( err < E_OK ) {			goto err_ret;		}		fd->waitReq = pkt;		fwd = WaitRequest;	} else {		fd->waitReq = NULL;		fwd = NoForward;	}	pkt->cmd.ret = err;	return fwd;err_ret:	DEBUG_PRINT(("fmpLockRecord err = %d\n", err));	fd->waitReq = NULL;	pkt->cmd.ret = err;	return NoForward;}/* * Release the locks of all records. */EXPORT void fmpUnlockAllRecord( FD *fd, OFCB *ofcb ){	FsInfo	*fsinfo = ofcb->fsinfo;	RCB	*rcb;	for ( rcb = FirstRCB(ofcb); rcb != EndRCB(ofcb); rcb = nextRCB(rcb) ) {		if ( rcb->lkfd == fd ) {			/* Release the lock  */			rcb->lkfd = NULL;			/* Release the waiting of a waiting request. */			removeLockWaitQue(rcb, fsinfo);		}	}}/* * Check whether some records are locked. */EXPORT ER fmpCheckLockAllRecord( OFCB *ofcb ){	RCB	*rcb;	for ( rcb = FirstRCB(ofcb); rcb != EndRCB(ofcb); rcb = nextRCB(rcb) ) {		if ( rcb->lkfd != NULL ) {			/* Locked */			return E_LOCK;		}	}	/* Not locked */	return E_OK;}/* * Forcefully release the lock waiting. */EXPORT ER fmpBreakLockWait( FmCmdPkt *waitReq, FsInfo *fsinfo ){	/* Deregister from the lock-waiting queue. */	QueRemove(&waitReq->cmd.q);	/* Return with E_DISWAI. */	waitReq->cmd.fno.w = FMI_BreakSysCall_FN;	waitReq->cmd.ret = E_DISWAI;	/* Register in the queue of resume requests. */	QueInsert(&waitReq->cmd.q, &fsinfo->resumeReq);	return E_OK;}

⌨️ 快捷键说明

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