📄 lockrec.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 + -