lcknfree.c
来自「db.* (pronounced dee-be star) is an adva」· C语言 代码 · 共 633 行 · 第 1/2 页
C
633 行
/*************************************************************************** * * * db.* * * open source database kernel * * * * Copyright (c) 2000 Centura Software Corporation. All rights reserved. * * * * Use of this software, whether in source code format, or in executable, * * binary object code form, is governed by the CENTURA OPEN SOURCE LICENSE * * which is fully described in the LICENSE.TXT file, included within this * * distribution of source code files. * * * **************************************************************************/#include "db.star.h"#include "rntmint.h"static int INTERNAL_FCN process_lock(struct lock_descr *, DB_TCHAR, DB_TASK *);static int INTERNAL_FCN keep_locks(struct lock_descr *, DB_TASK *);static int INTERNAL_FCN free_files(struct lock_descr *, DB_TASK *);static int INTERNAL_FCN lock_files(int, LOCK_REQUEST *, DB_TASK *);#define KEYMARK ((unsigned) 30000)/* ====================================================================== Establish record file locks*/int INTERNAL_FCN dreclock(int rec, DB_TCHAR *lock_type, DB_TASK *task, int dbn){ LOCK_REQUEST lr; RECORD_ENTRY *rec_ptr; int nrec; if (nrec_check(rec, &nrec, &rec_ptr, task) != S_OKAY) return (task->db_status); lr.item = rec; lr.type = *lock_type; return (dlock(1, &lr, task, dbn));}/* ====================================================================== Establish set file locks*/int INTERNAL_FCN dsetlock(int set, DB_TCHAR *lock_type, DB_TASK *task, int dbn){ LOCK_REQUEST lr; SET_ENTRY *set_ptr; int nset; if (nset_check(set, &nset, &set_ptr, task) != S_OKAY) return (task->db_status); lr.item = set; lr.type = *lock_type; return (dlock(1, &lr, task, dbn));}/* ====================================================================== Lock key file*/int INTERNAL_FCN dkeylock(long key, DB_TCHAR *lock_type, DB_TASK *task, int dbn){ int fld, rec; LOCK_REQUEST lr; RECORD_ENTRY *rec_ptr; FIELD_ENTRY *fld_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)); lr.item = (unsigned int)fld + KEYMARK; lr.type = *lock_type; return (dlock(1, &lr, task, dbn));}/* ====================================================================== Lock a group of records and/or sets*/int INTERNAL_FCN dlock(int count, LOCK_REQUEST *lrpkt, DB_TASK *task, int dbn){ register unsigned int item; register int i; register LOCK_REQUEST *lrpkt_ptr; struct lock_descr *ld_ptr = NULL; if (task->dbopen >= 2) return (task->db_status); task->lock_pkt->nfiles = 0; for (i = 0, lrpkt_ptr = lrpkt; (task->db_status == S_OKAY) && (i < count); ++i, ++lrpkt_ptr) { if (lrpkt_ptr->item >= KEYMARK) { item = task->field_table[lrpkt_ptr->item - KEYMARK].fd_keyno; ld_ptr = &task->key_locks[item]; } else if (lrpkt_ptr->item >= SETMARK) { item = NUM2INT(lrpkt_ptr->item - SETMARK, st_offset); if (item < (unsigned) ORIGIN(st_offset) || item >= (unsigned) (DB_REF(Size_st) + ORIGIN(st_offset))) dberr(S_INVSET); else ld_ptr = &task->set_locks[item]; } else if (lrpkt_ptr->item >= RECMARK) { item = NUM2INT(lrpkt_ptr->item - RECMARK, rt_offset); if (item < (unsigned) ORIGIN(rt_offset) || item >= (unsigned) (DB_REF(Size_rt) + ORIGIN(rt_offset))) dberr(S_INVREC); else if (task->record_table[item].rt_flags & STATIC) dberr(S_STATIC); else ld_ptr = &task->rec_locks[item]; } else dberr(S_INVNUM); if (task->db_status == S_OKAY) { process_lock(ld_ptr, (DB_TCHAR) lrpkt_ptr->type, task); /* if process_lock() fails, break out of loop after i is incremented */ } else break; } if (task->db_status == S_OKAY) lock_files(count, lrpkt, task); else count = i; /* only reset as many as were processed */ if (task->db_status != S_OKAY) { /* reset lock descriptor tables to previous state */ for (i = 0, lrpkt_ptr = lrpkt; i < count; ++i, ++lrpkt_ptr) { if (lrpkt_ptr->item >= KEYMARK) { item = task->field_table[lrpkt_ptr->item - KEYMARK].fd_keyno; ld_ptr = &task->key_locks[item]; } else if (lrpkt_ptr->item >= SETMARK) { item = NUM2INT(lrpkt_ptr->item - (unsigned) SETMARK, st_offset); ld_ptr = &task->set_locks[item]; } else if (lrpkt_ptr->item >= RECMARK) { item = NUM2INT(lrpkt_ptr->item - (unsigned) RECMARK, rt_offset); ld_ptr = &task->rec_locks[item]; } else continue; ld_ptr->fl_type = ld_ptr->fl_prev; } } return (task->db_status);}/* ====================================================================== Process set/record lock*/static int INTERNAL_FCN process_lock(struct lock_descr *ld_ptr, DB_TCHAR type, DB_TASK *task){ register int fl_lc; /* loop control */ FILE_NO fno; register unsigned short i; register DB_LOCKREQ *lockreq_ptr; FILE_NO *fl_ptr; FILE_NO fref; ld_ptr->fl_prev = ld_ptr->fl_type; switch (type) { case DB_TEXT('k'): if (!task->trans_id[0]) dberr(S_NOTRANS); else if (ld_ptr->fl_prev == DB_TEXT('f')) dberr(S_NOTLOCKED); else if (ld_ptr->fl_prev != DB_TEXT('x')) return (keep_locks(ld_ptr, task)); break; case DB_TEXT('r'): if (ld_ptr->fl_prev != DB_TEXT('f')) dberr(S_NOTFREE); else ld_ptr->fl_type = DB_TEXT('r'); break; case DB_TEXT('w'): if (!task->trans_id[0]) dberr(S_NOTRANS); else if (ld_ptr->fl_prev != DB_TEXT('f') && ld_ptr->fl_prev != DB_TEXT('r')) dberr(S_NOTFREE); else ld_ptr->fl_type = DB_TEXT('w'); break; case DB_TEXT('x'): if (ld_ptr->fl_prev != DB_TEXT('f') && ld_ptr->fl_prev != DB_TEXT('r')) dberr(S_NOTFREE); else ld_ptr->fl_type = DB_TEXT('x'); break; default: dberr(S_BADTYPE); } if (task->db_status == S_OKAY) { /* build lock request packet */ fl_ptr = (FILE_NO *) ld_ptr->fl_list; for (fl_lc = ld_ptr->fl_cnt; --fl_lc >= 0; ++fl_ptr) { fref = task->file_refs[fno = *fl_ptr]; if (fref == -1) continue; /* file is TEMPORARY */ for ( i = 0, lockreq_ptr = task->lock_pkt->locks; (i < task->lock_pkt->nfiles) && (lockreq_ptr->fref != fref); ++i, ++lockreq_ptr) ; /* null statement */ if (i < task->lock_pkt->nfiles) { /* file already is in lock request packet */ if (lockreq_ptr->type == DB_TEXT('r') || ld_ptr->fl_type == DB_TEXT('x')) lockreq_ptr->type = ld_ptr->fl_type; } else if (!task->excl_locks[fno] && (!task->app_locks[fno] || (ld_ptr->fl_type == DB_TEXT('w') && task->app_locks[fno] > 0) || (ld_ptr->fl_type == DB_TEXT('x')))) { /* add to lock request packet */ ++task->lock_pkt->nfiles; lockreq_ptr->fref = fref; lockreq_ptr->type = ld_ptr->fl_type; } } } return task->db_status;}/* ====================================================================== Lock database files*/static int INTERNAL_FCN lock_files( int count, LOCK_REQUEST *lrpkt, DB_TASK *task){ register int fl_lc; /* loop control */ struct lock_descr *ld_ptr; FILE_NO fno; register unsigned int item; int l; LOCK_REQUEST *lrpkt_ptr; int *appl_ptr; int *excl_ptr; FILE_NO *fl_ptr; DB_BOOLEAN clearStatic; if (send_lock_pkt(NULL, task) == S_OKAY) { /* update task->app_locks and excl_lock tables */ for (l = 0, lrpkt_ptr = lrpkt; l < count; ++l, ++lrpkt_ptr) { if (lrpkt_ptr->type == DB_TEXT('k')) continue; /* skip keep lock requests */ /* process each record/set lock */ if (lrpkt_ptr->item >= KEYMARK) { clearStatic = 0; item = task->field_table[lrpkt_ptr->item - KEYMARK].fd_keyno; ld_ptr = &task->key_locks[item]; } else if (lrpkt_ptr->item >= SETMARK) { /* Since all the records in the file are static, the file will be flagged as static. However, the set pointers CAN be updated in a static record, thus requiring the pages to be read in again. */ clearStatic = 1; item = NUM2INT(lrpkt_ptr->item - (unsigned) SETMARK, st_offset);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?