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 + -
显示快捷键?