lcknfree.c

来自「db.* (pronounced dee-be star) is an adva」· C语言 代码 · 共 633 行 · 第 1/2 页

C
633
字号
                ld_ptr = &task->set_locks[item];            }            else            {                clearStatic = 0;                item = NUM2INT(lrpkt_ptr->item - (unsigned) RECMARK, rt_offset);                ld_ptr = &task->rec_locks[item];            }                        fl_ptr = (FILE_NO *) ld_ptr->fl_list;            for (fl_lc = ld_ptr->fl_cnt; --fl_lc >= 0; ++fl_ptr)            {                /* process each file for each record/set lock */                fno = *fl_ptr;                if (task->file_table[fno].ft_flags & TEMPORARY)                    continue;                appl_ptr = &task->app_locks[fno];                excl_ptr = &task->excl_locks[fno];                if ((! *appl_ptr) && (! *excl_ptr))                {                    if (clearStatic || !(task->file_table[fno].ft_flags & STATIC))                    {                        /*                        Don't clear the cache if the timestamps match.                          ft_lmtimestamp     this is the value obtained last from                                                    the lock mgr                          ft_cachetimestamp  this was the timestamp value during                                                    previous communication                        If the cache does get cleared, update the stored timestamp.                        */#if 0                        if (task->file_table[fno].ft_lmtimestamp != task->file_table[fno].ft_cachetimestamp)                        {#endif                            dio_clrfile(fno, task); /* clear file's pages from cache */#if 0                            task->file_table[fno].ft_cachetimestamp = task->file_table[fno].ft_lmtimestamp;                        }#endif                    }                }                if (ld_ptr->fl_type == DB_TEXT('r'))                {                    if (*appl_ptr >= 0)                    {                        if (*appl_ptr == 0)                            STAT_lock(fno, STAT_LOCK_r, task);                        ++*appl_ptr;  /* increment if file free or read-locked */                    }                }                else                {                    if (ld_ptr->fl_type == DB_TEXT('w'))                    {                        *appl_ptr = -1;                        if (ld_ptr->fl_prev == DB_TEXT('r'))                            STAT_lock(fno, STAT_LOCK_r2w, task);                        else                            STAT_lock(fno, STAT_LOCK_w, task);                    }                    else if (ld_ptr->fl_type == DB_TEXT('x'))                    {                        ++*excl_ptr;                        if (ld_ptr->fl_prev == DB_TEXT('r'))                        {                            /* read to excl lock upgrade */                            --*appl_ptr;                            STAT_lock(fno, STAT_LOCK_r2x, task);                        }                        else                            STAT_lock(fno, STAT_LOCK_x, task);                    }                }            }        }    }    return task->db_status;}/* ======================================================================    Setup table to keep locks after transaction end*/static int INTERNAL_FCN keep_locks(    struct lock_descr *ld_ptr,    DB_TASK           *task){    register int      fl_lc;                 /* loop control */    register FILE_NO *fl_ptr;    /* Mark lock as kept */    ld_ptr->fl_kept = TRUE;    fl_ptr = (FILE_NO *) ld_ptr->fl_list;    for (fl_lc = ld_ptr->fl_cnt; --fl_lc >= 0; ++fl_ptr)    {        if (!(task->file_table[*fl_ptr].ft_flags & TEMPORARY))            ++task->kept_locks[*fl_ptr];    }    return (task->db_status);}/* ======================================================================    Free record lock*/int INTERNAL_FCN drecfree(int rec, DB_TASK *task, int dbn){    RECORD_ENTRY      *rec_ptr;    struct lock_descr *ld_ptr;    if (nrec_check(rec, &rec, &rec_ptr, task) != S_OKAY)        return (task->db_status);    if (task->dbopen >= 2)                /* exclusive access needs no locks */        return (task->db_status);    ld_ptr = &task->rec_locks[rec];    if (task->trans_id[0])        return (dberr(S_TRFREE));    if (ld_ptr->fl_type == DB_TEXT('f'))        return (dberr(S_NOTLOCKED));    free_files(ld_ptr, task);    ld_ptr->fl_type = DB_TEXT('f');    return task->db_status;}/* ======================================================================    Free set lock*/int INTERNAL_FCN dsetfree(int set, DB_TASK *task, int dbn){    SET_ENTRY         *set_ptr;    struct lock_descr *ld_ptr;    if (nset_check(set, &set, &set_ptr, task) != S_OKAY)        return (task->db_status);    if (task->dbopen >= 2)              /* exclusive access needs no locks */        return (task->db_status);    ld_ptr = &task->set_locks[set];    if (task->trans_id[0])        return (dberr(S_TRFREE));    if (ld_ptr->fl_type == DB_TEXT('f'))        return (dberr(S_NOTLOCKED));    free_files(ld_ptr, task);    ld_ptr->fl_type = DB_TEXT('f');    return task->db_status;}/* ======================================================================    Free key lock*/int INTERNAL_FCN dkeyfree(long key, DB_TASK *task, int dbn){    int                 fld,                        rec;    RECORD_ENTRY       *rec_ptr;    FIELD_ENTRY        *fld_ptr;    struct lock_descr  *ld_ptr;    if (nfld_check(key, &rec, &fld, &rec_ptr, &fld_ptr, task) != S_OKAY)        return (task->db_status);    if (fld_ptr->fd_key == NOKEY)        return (dberr(S_NOTKEY));    if (task->dbopen >= 2)              /* exclusive access needs no locks */        return (task->db_status);    ld_ptr = &task->key_locks[fld_ptr->fd_keyno];    if (task->trans_id[0])        return (dberr(S_TRFREE));    if (ld_ptr->fl_type == DB_TEXT('f'))        return (dberr(S_NOTLOCKED));    free_files(ld_ptr, task);    ld_ptr->fl_type = DB_TEXT('f');    return task->db_status;}/* ======================================================================    Free read-locked files associated with record or set*/static int INTERNAL_FCN free_files(    struct lock_descr *ld_ptr,    DB_TASK           *task){    register int      fl_lc;                 /* loop control */    FILE_NO           fno;    DB_LOCKREQ       *lockreq_ptr;    int              *appl_ptr;    FILE_NO           fref;    register FILE_NO *fl_ptr;    short             flushed = FALSE;    /* fill free packet */    task->lock_pkt->nfiles = task->free_pkt->nfiles = 0;    fl_ptr = (FILE_NO *) ld_ptr->fl_list;    for (fl_lc = ld_ptr->fl_cnt; --fl_lc >= 0; ++fl_ptr)    {        fno = *fl_ptr;        appl_ptr = &task->app_locks[fno];        fref = task->file_refs[fno];        if (fref == -1)            continue;      /* file is TEMPORARY */        if (ld_ptr->fl_type == DB_TEXT('r') && *appl_ptr > 0)        {            /* free read lock */            if (--*appl_ptr == 0 && task->excl_locks[fno] == 0)            {                task->free_pkt->frefs[task->free_pkt->nfiles++] = fref;                STAT_lock(fno, STAT_FREE_r, task);                /* reset key scan position */                if (task->file_table[fno].ft_type == DB_TEXT('k'))                    key_reset(fno, task);            }        }        else if (--task->excl_locks[fno] == 0)        {            if (!flushed)            {                flushed = TRUE;                dio_flush(task);            }            /* free exclusive access lock */            if (*appl_ptr > 0)            {                /* downgrade to read-lock */                lockreq_ptr = &task->lock_pkt->locks[task->lock_pkt->nfiles++];                lockreq_ptr->type = DB_TEXT('r');                lockreq_ptr->fref = fref;                STAT_lock(fno, STAT_LOCK_x2r, task);            }            else            {                /* free excl-lock */                task->free_pkt->frefs[task->free_pkt->nfiles++] = fref;                STAT_lock(fno, STAT_FREE_x, task);                            /* reset key scan position */                if (task->file_table[fno].ft_type == DB_TEXT('k'))                    key_reset(fno, task);            }        }        if (ld_ptr->fl_kept)        {            /* Remove hold on lock */            if (--task->kept_locks[fno] < 0)                return (dberr(S_BADLOCKS));            ld_ptr->fl_kept = FALSE;        }    }#if 0    if (task->lockMgrComm == LMC_GENERAL || task->lockMgrComm == LMC_TCP ||            task->lockMgrComm == LMC_QNX)    {        /* close files for downgrades */        FILE_NO        fno;        unsigned short pno;        if (task->lock_pkt->nfiles > 0)        {            for (fno = 0; fno < task->size_ft; ++fno)            {                for (pno = 0; pno < task->lock_pkt->nfiles; ++pno)                {                    if (task->file_refs[fno] == task->lock_pkt->locks[pno].fref)                    {                        dio_close(fno, task);                        break;                    }                }            }        }    }#endif    /* send any downgrades */    if (send_lock_pkt(NULL,task) == S_OKAY)    {        /* free any files */        send_free_pkt(task);    }    return task->db_status;}

⌨️ 快捷键说明

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