#define FL_LIST_ACCESS(ld_ptr) (FILE_NO *)(ld_ptr)->fl_list.ptr
#define FL_LIST_DEACCESS(ld_ptr) /**/
-#ifndef NO_TRANS
-#ifndef SINGLE_USER
-int rlb_status;
-static char type[5]; /* open type (s or x) */
-#endif
-#endif
-#ifndef NO_TRANS
-#ifndef GENERAL
-/* transaction activity file info */
-extern INT taf_count;
-extern char taf_files[TAFLIMIT][FILENMLEN];
-#endif
-#endif
/* Internal function prototypes */
#ifndef SINGLE_USER
-#ifndef NO_TRANS
-/* Set the number of lock request retries
-*/
-d_retries(num TASK_PARM)
-int num;
-TASK_DECL
-{
- DB_ENTER(NO_DB_ID TASK_ID LOCK_SET(LOCK_NONE));
-
-#ifndef SINGLE_USER
- lock_tries = num;
-#endif
- RETURN( db_status = S_OKAY );
-}
-#endif
-
-#ifndef NO_TRANS
-/* Set the lock request timeout value
-*/
-d_timeout(secs TASK_PARM)
-int secs;
-TASK_DECL
-{
-#ifdef SINGLE_USER
- return(db_status = S_OKAY);
-#else
- LM_SETTIME sto; /* send timeout packet */
- DB_ENTER(NO_DB_ID TASK_ID LOCK_SET(LOCK_ALL));
- if ( !dbopen ) RETURN( dberr(S_DBOPEN) );
-
- if ( dbopen == 1 ) {
- sto.fcn = L_SETTIME;
- sto.secs = secs;
- if ( nw_send(lsn, (MESSAGE *)&sto, sizeof(LM_SETTIME)) )
- RETURN( neterr() );
- db_timeout = secs;
- }
- RETURN( db_status = S_OKAY );
-#endif
-}
-#endif
/* Open db_VISTA database
#endif
#endif
-#ifndef NO_TRANS
-#ifndef GENERAL
- /* open transaction activity file */
- if ( taf_open() != S_OKAY )
- RETURN( db_status );
-#endif
-#endif
/* initialize multi-db tables */
if ( initdbt(dbnames) != S_OKAY ) RETURN( db_status );
if ( recovery_check() != S_OKAY ) RETURN(db_status);
#endif
#else
-#ifndef NO_TRANS
- /* [713] perform external recovery in single-user mode */
- if ( recovery_check() != S_OKAY ) RETURN(db_status);
-#endif
-#endif
-#ifndef NO_TRANS
- if ( use_ovfl ) {
- if ( o_setup() != S_OKAY ) RETURN( db_status );
- }
#endif
#ifdef DEBUG_DBLF
tsk->Db_timeout = TIMEOUT_DEF;
tsk->Db_lockmgr = 1;
#endif
-#ifndef NO_TRANS
- tsk->Dboptions = DCHAINUSE | TRLOGGING;
-#else
tsk->Dboptions = DCHAINUSE;
-#endif
return( db_status );
}
-#ifndef NO_TRANS
-/* Check for possible recovery
-*/
-static recovery_check()
-{
-#ifndef SINGLE_USER
- LM_TREND trend_pkt;
-#ifndef GENERAL
- int tn; /* transaction number */
- int tc; /* transaction count */
-#endif
-#endif
-
-#ifndef GENERAL
- /* open tr activity file */
- if ( taf_access() == S_OKAY ) {
- taf_release();
-#endif
-#ifdef SINGLE_USER
- if (taf_count != 0) {
- if (d_recover(taf_files[0] CURRTASK_PARM) != S_OKAY)
- return( db_status );
- taf_count = 0;
- }
-#else
-#ifndef GENERAL
- if ( tc = taf_count ) {
- /* perform recovery on each file */
- for ( tn = 0; tn < tc; ++tn ) {
- if ( d_recover(taf_files[0] CURRTASK_PARM) != S_OKAY ) return( db_status );
- }
- taf_count = 0;
- }
-#endif
-#endif
-#ifndef GENERAL
- }
-#endif
-#ifndef SINGLE_USER
- if ( db_lockmgr ) {
- /* tell lock manager that we're done */
- trend_pkt.fcn = L_RECDONE;
- if ( nw_send(lsn, (MESSAGE *)&trend_pkt, sizeof(LM_TREND)) )
- neterr();
- }
-#endif
-
- return( db_status );
-}
-#endif
}
#endif
-#ifndef NO_TRANS
-/* Build application file lock tables
-*/
-static int bld_lock_tables()
-{
-#ifndef SINGLE_USER
- int fd_lc; /* loop control */
- int st_lc; /* loop control */
- INT_P File_used;
-#define file_used File_used.ptr
- int rec;
- int mem, memtot;
- FILE_NO i;
- FILE_NO fl_cnt;
- struct lock_descr *ld_ptr;
- RECORD_ENTRY *rec_ptr;
- FIELD_ENTRY *fld_ptr;
- SET_ENTRY *set_ptr;
- MEMBER_ENTRY *mem_ptr;
- int *fu_ptr;
- FILE_NO *fl_ptr;
- unsigned new_size;
- unsigned old_size;
- int old_keyl_cnt;
-
- old_size = old_size_ft*sizeof(int);
- new_size = size_ft*sizeof(int);
- File_used.ptr = NULL;
- /* Macro references must be on one line for some compilers */
- if ((ALLOC_TABLE(&db_global.App_locks, new_size, old_size, "app_locks")
- != S_OKAY) ||
- (ALLOC_TABLE(&db_global.Excl_locks, new_size, old_size, "excl_locks")
- != S_OKAY) ||
- (ALLOC_TABLE(&db_global.Kept_locks, new_size, old_size, "kept_locks")
- != S_OKAY) ||
- (ALLOC_TABLE(&File_used, new_size, old_size, "file_used")
- != S_OKAY)) {
- return( db_status );
- }
-
- old_size = old_size_rt * sizeof(struct lock_descr);
- new_size = size_rt * sizeof(struct lock_descr);
- if ((ALLOC_TABLE(&db_global.Rec_locks, new_size, old_size, "rec_locks")
- != S_OKAY)) {
- return( db_status );
- }
-
- if ( size_st ) {
- new_size = size_st * sizeof(struct lock_descr);
- old_size = old_size_st * sizeof(struct lock_descr);
- /* Macro references must be on one line for some compilers */
- if (ALLOC_TABLE(&db_global.Set_locks, new_size, old_size, "set_locks")
- != S_OKAY ) {
- return( db_status );
- }
- }
-
- /* build rec_locks table */
- for (rec = old_size_rt, rec_ptr = &record_table[old_size_rt],
- ld_ptr = rec_locks;
- rec < size_rt;
- ++rec, ++rec_ptr, ++ld_ptr) {
- ld_ptr->fl_type = 'f';
- ld_ptr->fl_prev = 'f'; /*[367] init to free */
- ld_ptr->fl_kept = FALSE;
-
- /* put record's data file in list */
- file_used[rec_ptr->rt_file] = TRUE;
-
- /* add any key files to list */
- fl_cnt = 1; /* count of used files */
- for (fd_lc = size_fd - rec_ptr->rt_fields,
- fld_ptr = &field_table[rec_ptr->rt_fields];
- (--fd_lc >= 0) && (fld_ptr->fd_rec == rec);
- ++fld_ptr) {
- if ( fld_ptr->fd_key != NOKEY ) {
- fu_ptr = &file_used[fld_ptr->fd_keyfile];
- if (!*fu_ptr) {
- *fu_ptr = TRUE;
- ++fl_cnt;
- }
- }
- }
- ld_ptr->fl_cnt = fl_cnt;
- ld_ptr->fl_list.ptr =
- /* Macro references must be on one line for some compilers */
- (FILE_NO *)ALLOC(&ld_ptr->fl_list, fl_cnt*sizeof(FILE_NO), db_avname);
- if ( ld_ptr->fl_list.ptr == NULL ) return( dberr(S_NOMEMORY) );
- fl_ptr = ld_ptr->fl_list.ptr;
- for (i = 0, fu_ptr = file_used; i < size_ft; ++i, ++fu_ptr) {
- if (*fu_ptr) {
- *fu_ptr = FALSE;
- *fl_ptr++ = i;
- }
- }
- FL_LIST_DEACCESS(ld_ptr);
- }
- /* build set_locks table */
- if ( size_st ) {
- for (st_lc = size_st - old_size_st, set_ptr = &set_table[old_size_st],
- ld_ptr = set_locks;
- --st_lc >= 0; ++set_ptr, ++ld_ptr) {
- /* add owner's data file */
- file_used[record_table[set_ptr->st_own_rt].rt_file] = TRUE;
- ld_ptr->fl_type = 'f';
- ld_ptr->fl_prev = 'f'; /*[367] init to free */
- ld_ptr->fl_kept = FALSE;
-
- /* add member record data files to list */
- fl_cnt = 1; /* count of used files */
- for (mem = set_ptr->st_members, memtot = mem + set_ptr->st_memtot,
- mem_ptr = &member_table[mem];
- mem < memtot;
- ++mem, ++mem_ptr) {
- fu_ptr = &file_used[record_table[mem_ptr->mt_record].rt_file];
- if (!*fu_ptr) {
- *fu_ptr = TRUE;
- ++fl_cnt;
- }
- }
- ld_ptr->fl_cnt = fl_cnt;
- ld_ptr->fl_list.ptr =
- /* Macro references must be on one line for some compilers */
- (FILE_NO *)ALLOC(&ld_ptr->fl_list, fl_cnt*sizeof(FILE_NO), db_avname);
- if ( ld_ptr->fl_list.ptr == NULL ) return( dberr(S_NOMEMORY) );
- fl_ptr = ld_ptr->fl_list.ptr;
- for (i = 0, fu_ptr = file_used; i < size_ft; ++i, ++fu_ptr) {
- if (*fu_ptr) {
- *fu_ptr = FALSE;
- *fl_ptr++ = i;
- }
- }
- FL_LIST_DEACCESS(ld_ptr);
- }
- }
- /* build key_locks table */
- keyl_cnt = 0;
- old_keyl_cnt = keyl_cnt;
- for (fd_lc = size_fd - old_size_fd, fld_ptr = &field_table[old_size_fd];
- --fd_lc >= 0; ++fld_ptr) {
- /* count number of keys */
- if (fld_ptr->fd_key != NOKEY)
- ++keyl_cnt;
- }
- if ( keyl_cnt ) {
- old_size = old_keyl_cnt*sizeof(struct lock_descr);
- new_size = keyl_cnt*sizeof(struct lock_descr);
- /* Macro references must be on one line for some compilers */
- if (ALLOC_TABLE(&db_global.Key_locks, new_size, old_size, "key_locks")
- != S_OKAY) {
- return( db_status );
- }
- for (fd_lc = size_fd - old_size_fd, fld_ptr = &field_table[old_size_fd],
- ld_ptr = key_locks;
- --fd_lc >= 0; ++fld_ptr) {
- if (fld_ptr->fd_key != NOKEY) {
- ld_ptr->fl_type = 'f';
- ld_ptr->fl_prev = 'f'; /*[367] init to free */
- ld_ptr->fl_kept = FALSE;
- ld_ptr->fl_cnt = 1;
- ld_ptr->fl_list.ptr = (FILE_NO *)ALLOC(&ld_ptr->fl_list, ld_ptr->fl_cnt*sizeof(FILE_NO), "fl_list");
- if ( ld_ptr->fl_list.ptr == NULL ) return( dberr(S_NOMEMORY) );
- *(ld_ptr->fl_list.ptr) = fld_ptr->fd_keyfile;
- FL_LIST_DEACCESS(ld_ptr);
- ++ld_ptr;
- }
- }
- }
- lp_size = sizeof(LM_LOCK) + (size_ft-1)*sizeof(LM_LOCKREQ);
- fp_size = sizeof(LM_FREE) + (size_ft-1)*sizeof(INT);
- lock_pkt = (LM_LOCK *)ALLOC(&db_global.Lock_pkt, lp_size, "lock_pkt");
- free_pkt = (LM_FREE *)ALLOC(&db_global.Free_pkt, fp_size, "free_pkt");
- if ( !lock_pkt || !free_pkt ) return( dberr(S_NOMEMORY) );
- lock_pkt->fcn = L_LOCK;
- free_pkt->fcn = L_FREE;
- MEM_UNLOCK(&File_used);
- FREE(&File_used);
-#endif
-
- return( db_status = S_OKAY );
-}
-#endif
/****************************************/
if ( dbopen ) {
db_status = S_OKAY;
-#ifndef NO_TRANS
- /* in case they forgot to end the transaction */
- if ( trans_id )
- d_trabort(TASK_ONLY);
- else
-#ifndef SINGLE_USER
- if ( dbopen >= 2 )
-#endif
-#endif
dio_flush();
for (i = 0; i < size_ft; ++i) {
#endif
#endif
-#ifndef NO_TRANS
-#ifndef GENERAL
- taf_close();
-#endif
-#endif
#ifndef SINGLE_USER
d_freeall(TASK_ONLY);
#endif
-#ifndef NO_TRANS
- if ( use_ovfl ) o_free();
-#endif
/* termfree();
key_close();
sk_free();
dbwait_time = 1;
db_lockmgr = 1;
session_active = FALSE;
-#endif
-#ifndef NO_TRANS
- cache_ovfl = FALSE;
- ov_initaddr = 0L;
- ov_rootaddr = 0L;
- ov_nextaddr = 0L;
#endif
db_status = S_OKAY;
curr_rec = NULL_DBA;
}
}
-#ifndef NO_TRANS
-/* Establish record file locks
-*/
-d_reclock(rec, lock_type TASK_PARM DBN_PARM)
-int rec;
-char *lock_type;
-TASK_DECL
-DBN_DECL
-{
-#ifdef SINGLE_USER
- return(db_status = S_OKAY);
-#else
- LOCK_REQUEST lr;
-
- DB_ENTER(DB_ID TASK_ID LOCK_SET(LOCK_IO));
-
- lr.item = rec;
- lr.type = *lock_type;
-
- RETURN( d_lock(1, &lr TASK_PARM DBN_PARM) );
-#endif
-}
-#endif
-
-
-#ifndef NO_TRANS
-/* Establish set file locks
-*/
-d_setlock(set, lock_type TASK_PARM DBN_PARM)
-int set;
-char *lock_type;
-TASK_DECL
-DBN_DECL
-{
-#ifdef SINGLE_USER
- return (db_status = S_OKAY);
-#else
- LOCK_REQUEST lr;
-
- DB_ENTER(DB_ID TASK_ID LOCK_SET(LOCK_IO));
-
- lr.item = set;
- lr.type = *lock_type;
-
- RETURN( d_lock(1, &lr TASK_PARM DBN_PARM) );
-#endif
-}
-#endif
-
-#ifndef NO_TRANS
-/* Lock key file
-*/
-d_keylock(key, lock_type TASK_PARM DBN_PARM)
-long key; /* field number of key */
-char *lock_type;
-TASK_DECL
-DBN_DECL
-{
-#ifdef SINGLE_USER
- return (db_status = S_OKAY);
-#else
- int fld, rec;
- LOCK_REQUEST lr;
- RECORD_ENTRY *rec_ptr;
- FIELD_ENTRY *fld_ptr;
-
- DB_ENTER(DB_ID TASK_ID LOCK_SET(LOCK_IO));
-
- if (nfld_check(key, &rec, &fld, (RECORD_ENTRY * *)&rec_ptr, (FIELD_ENTRY * *)&fld_ptr) != S_OKAY)
- RETURN( db_status );
-
- if (fld_ptr->fd_key == NOKEY)
- RETURN( dberr(S_NOTKEY) );
-
- /* KEYMARK allows 'fld' to be recognized as a key file. It is already
- adjusted (in nfld_check) to INTernal format. Don't play with it in
- d_lock and lock_files.
- */
- lr.item = fld + KEYMARK;
- lr.type = *lock_type;
-
- RETURN( d_lock(1, &lr TASK_PARM DBN_PARM) );
-#endif
-}
-#endif
-
-#ifndef NO_TRANS
-/* Return lock status for record type
-*/
-d_reclstat(rec, lstat TASK_PARM DBN_PARM)
-int rec;
-char *lstat;
-TASK_DECL
-DBN_DECL
-{
-#ifdef SINGLE_USER
- *lstat = 'f';
- return( db_status = S_OKAY );
-#else
- RECORD_ENTRY *rec_ptr;
-
- DB_ENTER(DB_ID TASK_ID LOCK_SET(LOCK_NOIO));
-
- if (nrec_check(rec, &rec, (RECORD_ENTRY * *)&rec_ptr) != S_OKAY)
- RETURN( db_status );
-
- if ( dbopen >= 2 )
- *lstat = 'f';
- else {
- if (rec_ptr->rt_flags & STATIC)
- *lstat = 's';
- else
- *lstat = rec_locks[rec].fl_type;
- }
- RETURN( db_status = S_OKAY );
-#endif
-}
-#endif
-
-#ifndef NO_TRANS
-/* Return lock status for set type
-*/
-d_setlstat(set, lstat TASK_PARM DBN_PARM)
-int set;
-char *lstat;
-TASK_DECL
-DBN_DECL
-{
-#ifdef SINGLE_USER
- *lstat = 'f';
- return (db_status = S_OKAY);
-#else
- SET_ENTRY *set_ptr;
-
- DB_ENTER(DB_ID TASK_ID LOCK_SET(LOCK_NOIO));
-
- if (nset_check(set, &set, (SET_ENTRY * *)&set_ptr) != S_OKAY)
- RETURN( db_status );
-
- if ( dbopen >= 2 )
- *lstat = 'f';
- else
- *lstat = set_locks[set].fl_type;
-
- RETURN( db_status = S_OKAY );
-#endif
-}
-#endif
-
-#ifndef NO_TRANS
-/* Return lock status for key type
-*/
-d_keylstat(key, lstat TASK_PARM DBN_PARM)
-long key;
-char *lstat;
-TASK_DECL
-DBN_DECL
-{
-#ifdef SINGLE_USER
- *lstat = 'f';
- return (db_status = S_OKAY);
-#else
- int fld, rec;
- RECORD_ENTRY *rec_ptr;
- FIELD_ENTRY *fld_ptr;
- DB_ENTER(DB_ID TASK_ID LOCK_SET(LOCK_NOIO));
- if (nfld_check(key, &rec, &fld, (RECORD_ENTRY * *)&rec_ptr, (FIELD_ENTRY * *)&fld_ptr) != S_OKAY)
- RETURN( db_status );
- if (fld_ptr->fd_key == NOKEY)
- RETURN( dberr(S_NOTKEY) );
- if ( dbopen >= 2 )
- *lstat = 'f';
- else {
- if ( file_table[fld_ptr->fd_keyfile].ft_flags & STATIC )
- *lstat = 's';
- else
- *lstat = key_locks[fld_ptr->fd_keyno].fl_type;
- }
- RETURN( db_status = S_OKAY );
-#endif
-}
-#endif
-
-#ifndef NO_TRANS
-/* Lock a group of records and/or sets
-*/
-d_lock(count, lrpkt TASK_PARM DBN_PARM)
-int count;
-LOCK_REQUEST *lrpkt;
-TASK_DECL
-DBN_DECL
-{
-#ifdef SINGLE_USER
- return (db_status = S_OKAY);
-#else
- int item;
- int i;
- LOCK_REQUEST *lrpkt_ptr;
- struct lock_descr *ld_ptr;
- DB_ENTER(DB_ID TASK_ID LOCK_SET(LOCK_IO));
- if ( dbopen >= 2 )
- RETURN( db_status = S_OKAY );
- lock_pkt->nfiles = 0;
- for (i = 0, lrpkt_ptr = lrpkt;
- (db_status == S_OKAY) && (i < count);
- ++i, ++lrpkt_ptr) {
- if ( lrpkt_ptr->item >= KEYMARK ) {
- /* do not adjust lrpkt->item (see comment in d_keylock) */
- item = field_table[lrpkt_ptr->item - KEYMARK].fd_keyno;
- process_lock(&key_locks[item], lrpkt_ptr->type);
- }
- else if ( lrpkt_ptr->item >= SETMARK ) {
- item = NUM2INT(lrpkt_ptr->item - SETMARK, st_offset);
- process_lock(&set_locks[item], lrpkt_ptr->type);
- }
- else if ( lrpkt_ptr->item >= RECMARK ) {
- item = NUM2INT(lrpkt_ptr->item - RECMARK, rt_offset);
- if ( record_table[item].rt_flags & STATIC )
- dberr(S_STATIC);
- else
- process_lock(&rec_locks[item], lrpkt_ptr->type);
- }
- else
- dberr( S_INVNUM );
- }
- if ( db_status == S_OKAY )
- lock_files(count, lrpkt);
-
- if ( db_status != S_OKAY ) {
- /* reset lock descriptor tables to previous state */
- for (i = 0, lrpkt_ptr = lrpkt; i < count; ++i, ++lrpkt_ptr) {
- /* do not adjust lrpkt->item (see comment in d_keylock) */
- if ( lrpkt_ptr->item >= KEYMARK ) {
- item = field_table[lrpkt_ptr->item - KEYMARK].fd_keyno;
- ld_ptr = &key_locks[item];
- }
- else if ( lrpkt_ptr->item >= SETMARK ) {
- item = NUM2INT(lrpkt_ptr->item - SETMARK, st_offset);
- ld_ptr = &set_locks[item];
- }
- else if ( lrpkt_ptr->item >= RECMARK ) {
- item = NUM2INT(lrpkt_ptr->item - RECMARK, rt_offset);
- ld_ptr = &rec_locks[item];
- }
- else
- continue;
- ld_ptr->fl_type = ld_ptr->fl_prev;
- }
- }
- RETURN( db_status );
-#endif
-}
-#endif
#ifndef SINGLE_USER
#endif
-#ifndef NO_TRANS
-/* Lock database files
-*/
-static lock_files(count, lrpkt )
-int count;
-LOCK_REQUEST *lrpkt;
-{
-#ifndef SINGLE_USER
- int fl_lc; /* loop control */
- struct lock_descr *ld_ptr;
- FILE_NO fno;
- int item;
- int l;
- LOCK_REQUEST *lrpkt_ptr;
- int *appl_ptr, *excl_ptr;
- FILE_NO *fl_ptr;
-
- lock_reply.status = L_OKAY;
- if ( lock_pkt->nfiles == 0 ) goto skip_send;
-
- if ( send_lock() != S_OKAY )
- return( db_status );
-
-skip_send:
- switch ( lock_reply.status ) {
- case L_OKAY:
- /* update app_locks and excl_lock tables */
- for (l = 0, lrpkt_ptr = lrpkt; l < count; ++l, ++lrpkt_ptr) {
- if (lrpkt_ptr->type == 'k')
- continue; /* skip keep lock requests */
- /* process each record/set lock */
- /* do not adjust lrpkt->item (see comment in d_keylock) */
- if ( lrpkt_ptr->item >= KEYMARK ) {
- item = field_table[lrpkt_ptr->item - KEYMARK].fd_keyno;
- ld_ptr = &key_locks[item];
- }
- else if ( lrpkt_ptr->item >= SETMARK ) {
- item = NUM2INT(lrpkt_ptr->item - SETMARK, st_offset);
- ld_ptr = &set_locks[item];
- }
- else {
- item = NUM2INT(lrpkt_ptr->item - RECMARK, rt_offset);
- ld_ptr = &rec_locks[item];
- }
- for (fl_lc = ld_ptr->fl_cnt, fl_ptr = FL_LIST_ACCESS(ld_ptr);
- --fl_lc >= 0; ++fl_ptr) {
- /* process each file for each record/set lock */
- fno = *fl_ptr;
- appl_ptr = &app_locks[fno];
- excl_ptr = &excl_locks[fno];
- if ( !*appl_ptr && !*excl_ptr ) {
- /* clear file's pages from cache */
- dio_clrfile(fno);
- }
- if ( ld_ptr->fl_type == 'r' ) {
- if ( *appl_ptr >= 0 )
- /* increment if file free or read-locked */
- ++*appl_ptr;
- }
- else {
- if ( ld_ptr->fl_type == 'w' )
- *appl_ptr = -1;
- else if ( ld_ptr->fl_type == 'x' ) {
- ++*excl_ptr;
- if ( ld_ptr->fl_prev == 'r' ) {
- /* read to excl lock upgrade */
- --*appl_ptr;
- }
- }
- }
- }
- FL_LIST_DEACCESS(ld_ptr);
- }
- break;
- case L_UNAVAIL:
- case L_TIMEOUT:
- return( db_status = S_UNAVAIL );
- default:
- return( dberr(S_SYSERR) );
- }
-#endif
-
- return( db_status = S_OKAY );
-}
-#endif
-
-#ifndef NO_TRANS
-/* Send lock request
-*/
-static int send_lock()
-{
-#ifndef SINGLE_USER
- LM_TREND trend_pkt;
- int send_size, recv_size;
-
- if ( lock_pkt->nfiles ) {
- /* send lock request */
- send_size = sizeof(LM_LOCK) + (lock_pkt->nfiles-1)*sizeof(LM_LOCKREQ);
- if ( send_size > lp_size )
- return( dberr(S_SYSERR) );
-
-req_locks:
-#ifdef MONITOR
- printf("nw_send(lsn,lock_pkt->fcn=%ld,size=%d\n",lock_pkt->fcn,send_size);
-#endif
- if ( nw_send(lsn, (MESSAGE *)lock_pkt, send_size) )
- return( neterr() );
- if ( nw_rcvmsg(lsn, (MESSAGE *)&lock_reply, sizeof(LR_LOCK), &recv_size) )
- return( neterr() );
-#ifdef MONITOR
- printf("nw_rcvmsg(lock_reply.fcn=%ld,lock_reply.status=%d\n",
- lock_reply.fcn,lock_reply.status);
-#endif
- /* request must always be granted */
- if ( lock_reply.fcn != L_LOCK )
- return( dberr(S_NETSYNC) );
- if (lock_reply.status == L_RECOVER) {
- /* perform auto-recovery */
- d_recover(lock_reply.logfile CURRTASK_PARM);
-
- /* tell lock mgr we're done */
- trend_pkt.fcn = L_RECDONE;
- if (nw_send(lsn, (MESSAGE *)&trend_pkt, sizeof(LM_TREND)))
- return( neterr() );
-
- /* re-issue lock request */
- goto req_locks;
- }
- if (lock_reply.status == L_QUEUEFULL) {
- sleep(dbwait_time);
- goto req_locks;
- }
- }
-#endif
-
- return( db_status = S_OKAY );
-}
-#endif
-
-
-#ifndef NO_TRANS
-/* Free key lock
-*/
-d_keyfree(key TASK_PARM DBN_PARM)
-long key;
-TASK_DECL
-DBN_DECL
-{
-#ifdef SINGLE_USER
- return (db_status = S_OKAY);
-#else
- int fld, rec;
- RECORD_ENTRY *rec_ptr;
- FIELD_ENTRY *fld_ptr;
- struct lock_descr *ld_ptr;
-
- DB_ENTER(DB_ID TASK_ID LOCK_SET(LOCK_IO));
-
- if (nfld_check(key, &rec, &fld, (RECORD_ENTRY * *)&rec_ptr, (FIELD_ENTRY * *)&fld_ptr) != S_OKAY)
- RETURN( db_status );
-
- if ( fld_ptr->fd_key == NOKEY )
- RETURN( dberr(S_NOTKEY) );
-
- if ( dbopen >= 2 ) /* exclusive access needs no locks */
- RETURN( db_status = S_OKAY );
-
- ld_ptr = &key_locks[fld_ptr->fd_keyno];
- if ( trans_id )
- RETURN( dberr(S_TRFREE) );
-
- if ( ld_ptr->fl_type == 'f' )
- RETURN( dberr(S_NOTLOCKED) );
-
- free_files(ld_ptr);
- ld_ptr->fl_type = 'f';
-
- RETURN( db_status );
-#endif
-}
-#endif
#ifndef SINGLE_USER
}
#endif
-#ifndef NO_TRANS
-/* Free record lock
-*/
-d_recfree(rec TASK_PARM DBN_PARM)
-int rec;
-TASK_DECL
-DBN_DECL
-{
-#ifdef SINGLE_USER
- return (db_status = S_OKAY);
-#else
- RECORD_ENTRY *rec_ptr;
- struct lock_descr *ld_ptr;
-
- DB_ENTER(DB_ID TASK_ID LOCK_SET(LOCK_IO));
-
- if (nrec_check(rec, &rec, (RECORD_ENTRY * *)&rec_ptr) != S_OKAY)
- RETURN( db_status );
-
- if ( dbopen >= 2 ) /* exclusive access needs no locks */
- RETURN( db_status = S_OKAY );
-
- ld_ptr = &rec_locks[rec];
-
- if ( trans_id )
- RETURN( dberr(S_TRFREE) );
-
- if ( ld_ptr->fl_type == 'f' )
- RETURN( dberr(S_NOTLOCKED) );
-
- free_files(ld_ptr);
- ld_ptr->fl_type = 'f';
-
- RETURN( db_status );
-#endif
-}
-#endif
-
-#ifndef NO_TRANS
-/* Free set lock
-*/
-d_setfree(set TASK_PARM DBN_PARM)
-int set;
-TASK_DECL
-DBN_DECL
-{
-#ifdef SINGLE_USER
- return (db_status = S_OKAY);
-#else
- SET_ENTRY *set_ptr;
- struct lock_descr *ld_ptr;
-
- DB_ENTER(DB_ID TASK_ID LOCK_SET(LOCK_IO));
-
- if (nset_check(set, &set, (SET_ENTRY * *)&set_ptr) != S_OKAY)
- RETURN( db_status );
-
- if ( dbopen >= 2 ) /* exclusive access needs no locks */
- RETURN( db_status = S_OKAY );
-
- ld_ptr = &set_locks[set];
-
- if ( trans_id )
- RETURN( dberr(S_TRFREE) );
- if ( ld_ptr->fl_type == 'f' )
- RETURN( dberr(S_NOTLOCKED) );
-
- free_files(ld_ptr);
- ld_ptr->fl_type = 'f';
-
- RETURN( db_status );
-#endif
-}
-#endif
}
#endif
-#ifndef NO_TRANS
-/* free all locked files
-*/
-d_freeall(TASK_ONLY)
-TASK_DECL
-{
-#ifdef SINGLE_USER
- return (db_status = S_OKAY);
-#else
- int i;
- FILE_NO *fref_ptr;
- int *appl_ptr;
-
- DB_ENTER(NO_DB_ID TASK_ID LOCK_SET(LOCK_IO));
-
- if ( ! dbopen ) RETURN( dberr(S_DBOPEN) );
-
- if ( dbopen >= 2 ) /* exclusive access needs no locks */
- RETURN( db_status = S_OKAY );
-
- if ( trans_id ) RETURN( dberr(S_TRFREE) );
-
- free_pkt->nfiles = 0;
- for (i = 0, fref_ptr = file_refs, appl_ptr = app_locks;
- i < size_ft;
- ++i, ++fref_ptr, ++appl_ptr) {
- if (*appl_ptr) {
- *appl_ptr = FALSE;
- if (!excl_locks[i])
- free_pkt->frefs[free_pkt->nfiles++] = *fref_ptr;
- }
- }
- /* send free files packet */
- if ( send_free() != S_OKAY )
- RETURN( db_status );
-
- /* reset all lock descriptors */
- reset_locks();
-
- /* reset all key file positions */
- key_reset(size_ft);
-
- /* Clear cache pages and return */
- RETURN( dio_clear() );
-#endif
-}
-#endif
#ifndef SINGLE_USER
}
#endif
-#ifndef NO_TRANS
-/* Send free files packet
-*/
-static int send_free()
-{
-#ifndef SINGLE_USER
- int send_size;
- /* send any free packets */
- if ( free_pkt->nfiles ) {
- send_size = sizeof(LM_FREE) + (free_pkt->nfiles-1)*sizeof(INT);
- if ( send_size > fp_size )
- return ( dberr(S_SYSERR) );
- if ( nw_send(lsn, (MESSAGE *)free_pkt, send_size) )
- return( neterr() );
- }
-#endif
- return( db_status = S_OKAY );
-}
-#endif
-#ifndef NO_TRANS
-/*------------------------------------------------------------------------
- Record Lock Bit Functions
-------------------------------------------------------------------------*/
-/* Set record lock bit of current record
-*/
-d_rlbset(TASK_ONLY)
-TASK_DECL
-{
-#ifndef SINGLE_USER
- FILE_NO file;
- INT rid;
- int record_lock;
-#endif
- DB_ENTER(NO_DB_ID TASK_ID LOCK_SET(LOCK_IO));
- if ( ! curr_rec ) RETURN( dberr(S_NOCR) );
-
-#ifndef SINGLE_USER
- file = NUM2INT((FILE_NO)((curr_rec >> FILESHIFT) & FILEMASK), ft_offset);
-
- if ( dbopen == 1 &&
- (record_lock = (app_locks[file] >= 0 && !excl_locks[file])) ) {
- /* request record-lock on file */
- lock_pkt->nfiles = 1;
- lock_pkt->locks[0].type = 'R';
- lock_pkt->locks[0].fref = file_refs[file];
- if ( send_lock() != S_OKAY ) RETURN( db_status );
- if ( lock_reply.status != L_OKAY )
- RETURN( db_status = S_UNAVAIL );
- }
- if ( dio_rrlb(curr_rec, &rid) != S_OKAY )
- RETURN( db_status );
- if ( rid & RLBMASK )
- rlb_status = S_LOCKED;
- else {
- rid |= RLBMASK;
- rlb_status = dio_wrlb(curr_rec, rid);
- }
- if ( dbopen == 1 && record_lock ) {
- /* free or downgrade record-lock on file */
- if ( app_locks[file] ) {
- lock_pkt->nfiles = 1;
- lock_pkt->locks[0].type = 'r';
- lock_pkt->locks[0].fref = file_refs[file];
- if ( send_lock() != S_OKAY ) RETURN( db_status );
- }
- else {
- free_pkt->nfiles = 1;
- free_pkt->frefs[0] = file_refs[file];
- if ( send_free() != S_OKAY ) RETURN( db_status );
- }
- }
- RETURN( db_status = rlb_status );
-#else
- RETURN( db_status = S_OKAY );
-#endif
-}
-#endif
-#ifndef NO_TRANS
-/* Clear record lock bit of current record
-*/
-d_rlbclr(TASK_ONLY)
-TASK_DECL
-{
-#ifndef SINGLE_USER
- FILE_NO file;
- INT rid;
-#endif
- DB_ENTER(NO_DB_ID TASK_ID LOCK_SET(LOCK_IO));
- if ( ! curr_rec ) RETURN( dberr(S_NOCR) );
-#ifndef SINGLE_USER
- file = NUM2INT((FILE_NO)((curr_rec >> FILESHIFT) & FILEMASK), ft_offset);
-
- /* ensure that changes are allowed */
- if (dbopen == 1 && trans_id && app_locks[file] >= 0 && !excl_locks[file])
- RETURN( dberr(S_NOTLOCKED) );
-
- if ( dbopen == 1 && ! trans_id ) {
- /* request record-lock on file */
- lock_pkt->nfiles = 1;
- lock_pkt->locks[0].type = 'R';
- lock_pkt->locks[0].fref = file_refs[file];
- if ( send_lock() != S_OKAY ) RETURN( db_status );
- if ( lock_reply.status != L_OKAY )
- RETURN( db_status = S_UNAVAIL );
- }
- /* read rlb */
- if ( dio_rrlb(curr_rec, &rid) != S_OKAY )
- RETURN( db_status );
-
- /* clear rlb */
- rid &= ~RLBMASK;
- rlb_status = S_UNLOCKED;
- dio_wrlb(curr_rec, rid);
-
- if ( dbopen == 1 && ! trans_id ) {
- /* free or downgrade record-lock on file */
- if ( app_locks[file] ) {
- lock_pkt->nfiles = 1;
- lock_pkt->locks[0].type = 'r';
- lock_pkt->locks[0].fref = file_refs[file];
- if ( send_lock() != S_OKAY ) RETURN( db_status );
- }
- else {
- free_pkt->nfiles = 1;
- free_pkt->frefs[0] = file_refs[file];
- if ( send_free() != S_OKAY ) RETURN( db_status );
- }
- }
-#else
- db_status = S_OKAY;
-#endif
- RETURN( db_status );
-}
-#endif
-
-
-#ifndef NO_TRANS
-/* Test record lock bit of current record
-*/
-d_rlbtst(TASK_ONLY)
-TASK_DECL
-{
-#ifndef SINGLE_USER
- INT rid;
-#endif
-
- DB_ENTER(NO_DB_ID TASK_ID LOCK_SET(LOCK_IO));
-
- if ( ! curr_rec ) RETURN( dberr(S_NOCR) );
-
-#ifndef SINGLE_USER
- if ( dio_rrlb(curr_rec, &rid) != S_OKAY )
- RETURN( db_status );
-
- if ( rid & RLBMASK )
- db_status = S_LOCKED;
- else
- db_status = S_UNLOCKED;
-
- RETURN( rlb_status = db_status );
-#else
- RETURN( db_status = S_UNLOCKED );
-#endif
-
-}
-#endif
-
-
-
-#ifndef NO_TRANS
-/*------------------------------------------------------------------------
- Database Transaction Processing Functions
-------------------------------------------------------------------------*/
-
-/* Begin transaction
-*/
-d_trbegin(tid TASK_PARM)
-const char *tid;
-TASK_DECL
-{
- DB_ENTER(NO_DB_ID TASK_ID LOCK_SET(LOCK_IO));
-
- db_status = S_OKAY;
-
- if ( ! dbopen ) RETURN( dberr(S_DBOPEN) );
-
- if ( tid == NULL ) RETURN( dberr(S_TRANSID) );
-
-
- if ( trans_id ) RETURN( dberr(S_TRACTIVE) );
-
- /* changes were possible outside a transaction */
- dio_flush();
-
- if ( use_ovfl ) {
- o_init();
- }
- trans_id = tid;
- RETURN( db_status );
-}
-#endif
-
-
-#ifndef NO_TRANS
-/* End transaction
-*/
-d_trend(TASK_ONLY)
-TASK_DECL
-{
-#ifndef SINGLE_USER
- int ft_lc; /* loop control */
- LM_TRCOMMIT trcom_pkt;
- LM_TREND trend_pkt;
- LM_LOCKREQ *lockreq_ptr;
- FILE_NO *fref_ptr;
- int *appl_ptr, *keptl_ptr, *excl_ptr;
-#endif
-
- DB_ENTER(NO_DB_ID TASK_ID LOCK_SET(LOCK_IO));
-
- db_status = S_OKAY;
- if( ! trans_id ) RETURN( dberr(S_TRNOTACT) );
-
- if( trlog_flag )
- /* mark start of trx in archive log file */
- d_trmark();
-
- /* flush data to database or overflow */
- if ( dio_flush() != S_OKAY ) RETURN( db_status );
-
- if ( (dboptions & TRLOGGING) && use_ovfl ) {
- /* End trx using overflow file */
-
- /* flush recovery data to overflow file */
- if ( o_flush() != S_OKAY ) RETURN( db_status );
-
-#ifndef SINGLE_USER
- trcom_pkt.fcn = L_TRCOMMIT;
- strcpy(trcom_pkt.logfile, dblog);
- if ( nw_send(lsn, (MESSAGE *)&trcom_pkt, sizeof(LM_TRCOMMIT)) )
- RETURN( neterr() );
-#endif
- trcommit = TRUE;
-
-#ifndef GENERAL
- if ( taf_add(dblog) != S_OKAY ) RETURN( db_status ); /* after nw_send */
-#endif
-
- /* allow for user interrupt to test recovery */
- if ( db_txtest ) dberr(S_DEBUG);
-
- if( cache_ovfl ) {
- /* update db from overflow file */
- if ( o_update() != S_OKAY ) RETURN( db_status );
- }
-
- /* flush modified cache data to database */
- if ( dio_flush() != S_OKAY ) RETURN( db_status );
-
-#ifndef GENERAL
- if ( taf_del(dblog) != S_OKAY ) RETURN( db_status ); /* before nw_send */
-#endif
- }
-#ifndef SINGLE_USER
- trend_pkt.fcn = L_TREND;
- if ( nw_send(lsn, (MESSAGE *)&trend_pkt, sizeof(LM_TREND)) )
- RETURN( neterr() );
-#endif
- trcommit = FALSE;
-
- if( trlog_flag )
- /* mark end of trx in archive log file */
- d_trbound();
-
- trans_id = NULL;
- o_init(); /*[305] clear cache_ovfl flag */
-
-#ifndef SINGLE_USER
- if ( dbopen == 1 ) {
- /* free unkept, non-exclusive file locks */
- lock_pkt->nfiles = free_pkt->nfiles = 0;
- for (ft_lc = size_ft, fref_ptr = file_refs, appl_ptr = app_locks,
- keptl_ptr = kept_locks, excl_ptr = excl_locks;
- --ft_lc >= 0; ++fref_ptr, ++appl_ptr, ++keptl_ptr, ++excl_ptr) {
- if (*excl_ptr)
- *appl_ptr = *keptl_ptr;
- else if ( *appl_ptr == -1 ) {
- if ( (*appl_ptr = *keptl_ptr) > 0 ) {
- lockreq_ptr = &lock_pkt->locks[lock_pkt->nfiles++];
- lockreq_ptr->type = 'r';
- lockreq_ptr->fref = *fref_ptr;
- }
- else
- free_pkt->frefs[free_pkt->nfiles++] = *fref_ptr;
- }
- else if ( *appl_ptr && (*appl_ptr = *keptl_ptr) == 0 )
- free_pkt->frefs[free_pkt->nfiles++] = *fref_ptr;
- *keptl_ptr = 0;
- }
- /* send lock downgrade request */
- if ( send_lock() != S_OKAY || send_free() != S_OKAY )
- RETURN( db_status );
-
- /* clear lock descriptors */
- reset_locks();
-
- /* reset all key file positions */
- key_reset(size_ft);
-
- /* clear page buffers */
- dio_clear();
- }
-#endif
- RETURN( db_status );
-}
-#endif
-
-
-#ifndef NO_TRANS
-/* Abort transaction
-*/
-d_trabort(TASK_ONLY)
-TASK_DECL
-{
-#ifdef SINGLE_USER
- DB_ENTER(NO_DB_ID TASK_ID LOCK_SET(LOCK_IO));
- if (!trans_id)
- RETURN (dberr(S_TRNOTACT));
- trans_id = NULL;
- dio_pzclr(); /*[425] clear page zero BEFORE dio_clear */
- dio_clear(); /*[353] clear cache */
- RETURN (db_status = S_OKAY);
-#else
- int i;
- int *keptl_ptr;
- struct lock_descr *ld_ptr;
-
- DB_ENTER(NO_DB_ID TASK_ID LOCK_SET(LOCK_IO));
-
- db_status = S_OKAY;
- if ( ! trans_id ) RETURN( dberr(S_TRNOTACT) );
-
- if ( dbopen == 1 ) {
- /* Revert any kept locks to unkept status */
- for (i = 0, keptl_ptr = kept_locks; i < size_ft; ++i, ++keptl_ptr)
- *keptl_ptr = 0;
- for (i = 0, ld_ptr = rec_locks; i < size_rt; ++i, ++ld_ptr)
- ld_ptr->fl_kept = FALSE;
- for (i = 0, ld_ptr = set_locks; i < size_st; ++i, ++ld_ptr)
- ld_ptr->fl_kept = FALSE;
- for (i = 0, ld_ptr = key_locks; i < keyl_cnt; ++i, ++ld_ptr)
- ld_ptr->fl_kept = FALSE;
- }
- trans_id = NULL;
- o_init(); /*[305] clear cache_ovfl flag */
-
- dio_pzclr(); /*[425] clear page zero BEFORE d_freeall */
- if ( dbopen == 1 ) d_freeall(TASK_ONLY);
- dio_clear();
-
- RETURN( db_status = S_OKAY );
-#endif
-}
-#endif
#ifndef SINGLE_USER
/* Report a network error
int debugging_dio_close = FALSE;
#endif
-#ifndef NO_TRANS
-
-/* On MS-DOS networks, files must be closed whenever a lock is freed.
- Function dio_clrfile is called whenever a lock is freed to clear
- from the cache the pages of the file whose lock is being freed.
- CLosing and opening files on Unix, VMS and other host computers,
- however, is very slow and is not necessary for database integrity.
- The following constant definition specifies whether or not the files
- need to be closed. A definition per supported MS-DOS compiler is
- required.
-*/
-#ifdef MSC
-#define CLOSE_FILES
-#endif
-#ifdef LAT
-#define CLOSE_FILES
-#endif
-#ifdef WIZ
-#define CLOSE_FILES
-#endif
-#ifdef TURBO
-#define CLOSE_FILES
-#endif
-/*------------ transaction logging data ------------*/
-#define DEFIXPAGES 4 /* default number of index cache pages */
-#define MINIXPAGES 2 /* minimum number of index cache pages */
-int ix_pgtab_sz = DEFIXPAGES;
-LOOKUP_ENTRY_P Ix_lookup = POINTER_INIT(); /* index page lookup table */
-PAGE_ENTRY_P Ixpg_table = POINTER_INIT(); /* index page table */
-static int ixpg_lru_slot; /* least recently accessed ix page */
-
-/* transaction logging enabled flag */
-int trlog_flag = 0; /* set only by user implemented functions */
-
-BOOLEAN use_ovfl = YES; /* Default to using overflow */
-CHAR_P Dbpgbuff = POINTER_INIT(); /* allocated by dio_init used by o_update */
-/*------------ end of transaction logging data ------------*/
-#endif /* NO_TRANS */
#ifndef SINGLE_USER
#define EXCL_OPEN() (dbopen >= 2)
static int dio_pzinit(P0);
static int clear_cache(P1(FILE_NO) Pi(FILE_NO));
static int dio_pzflush(P0);
-#ifdef NO_TRANS
static int dio_in(P1(PAGE_ENTRY *) Pi(LOOKUP_ENTRY *));
-#else
-static int dio_in(P1(PAGE_ENTRY *) Pi(LOOKUP_ENTRY *)
- Pi(BOOLEAN));
-#endif
#define used_files Used_files.ptr
#define db_lookup Db_lookup.ptr
db_pgtab_sz = (dbpgs <= MINDBPAGES) ? MINDBPAGES : dbpgs;
-#ifndef NO_TRANS
- if ( use_ovfl ) {
- ix_pgtab_sz = (ixpgs <= MINIXPAGES) ? MINIXPAGES : ixpgs;
- }
-#endif
return( db_status = S_OKAY );
}
if ( page_size > largest_page ) {
if ( (tempbuff = ALLOC(&Tempbuff, page_size, "tempbuff")) == NULL )
return( dberr(S_NOMEMORY) );
-#ifndef NO_TRANS
- MEM_UNLOCK(&Dbpgbuff);
- FREE(&Dbpgbuff);
- Dbpgbuff = Tempbuff;
-#endif
largest_page = page_size;
}
#ifdef DEBUG_DIO
cache_init((int)db_pgtab_sz, db_lookup, dbpg_table, (int)page_size);
/***cache_init(db_pgtab_sz, db_lookup, dbpg_table, page_size);****/
if (db_status != S_OKAY) return(db_status);
-#ifndef NO_TRANS
- if ( use_ovfl ) {
- ix_lookup =
- /* Macro references must be on one line for some compilers */
- (LOOKUP_ENTRY *)
- ALLOC(&Ix_lookup, ix_pgtab_sz*sizeof(LOOKUP_ENTRY),"ix_lookup");
- ixpg_table =
- /* Macro references must be on one line for some compilers */
- (PAGE_ENTRY *)
- ALLOC(&Ixpg_table, ix_pgtab_sz*sizeof(PAGE_ENTRY), "ixpg_table");
- if ( !ix_lookup || !ixpg_table )
- return( dberr(S_NOMEMORY) );
-
- cache_init(ix_pgtab_sz, ix_lookup, ixpg_table, IX_PAGESIZE);
- if (db_status != S_OKAY)
- return (db_status);
-
- if ( (dbpgbuff = ALLOC(&Dbpgbuff, page_size, "dbpgbuff")) == NULL )
- return( dberr(S_NOMEMORY) );
-
- ixpg_lru_slot = 0;
- }
-#endif /* NO_TRANS */
last_file = 0;
dbpg_lru_slot = 0;
no_modheld = 0;
pg_ptr->recently_used = FALSE;
pg_ptr->modified = FALSE;
pg_ptr->holdcnt = 0;
-#ifndef NO_TRANS
- pg_ptr->ovfl_addr = 0L;
-#endif
pg_ptr->buff = ALLOC(&pg_ptr->Buff, pgsize, db_avname);
if (pg_ptr->buff == NULL) {
#ifdef DEBUG_DIO
}
MEM_UNLOCK(&Dbpg_table);
FREE(&Dbpg_table);
-#ifndef NO_TRANS
- if ( use_ovfl ) {
- MEM_UNLOCK(&Ix_lookup);
- FREE(&Ix_lookup);
- for (pgt_lc = ix_pgtab_sz, pg_ptr = ixpg_table; --pgt_lc >= 0; ++pg_ptr) {
- MEM_UNLOCK(&pg_ptr->Buff);
- FREE(&pg_ptr->Buff);
- }
- MEM_UNLOCK(&Ixpg_table);
- FREE(&Ixpg_table);
- MEM_UNLOCK(&Dbpgbuff);
- FREE(&Dbpgbuff);
- }
-#endif
} /* dio_free() */
}
pg_ptr->recently_used = FALSE;
pg_ptr->holdcnt = 0;
-#ifndef NO_TRANS
- pg_ptr->ovfl_addr = 0L;
-#endif
++lu_ptr;
}
}
int dio_flush()
{
int pgt_lc; /* loop control */
-#ifndef NO_TRANS
- int fno;
-#endif
PAGE_ENTRY *pg_ptr;
LOOKUP_ENTRY *lu_ptr;
for (pgt_lc = db_pgtab_sz, pg_ptr = dbpg_table; --pgt_lc >= 0; ++pg_ptr) {
if (!pg_ptr->modified) {
-#ifndef NO_TRANS
- pg_ptr->ovfl_addr = 0L; /*[612]*/
-#endif
continue;
}
lu_ptr = &db_lookup[pg_ptr->lu_slot];
-#ifndef NO_TRANS
- if ((dboptions & TRLOGGING) && trans_id && !trcommit && use_ovfl) {
- /* flush to overflow/log file -- before tr commit */
- if (o_write(pg_ptr, lu_ptr) != S_OKAY) return( db_status );
- if ( lu_ptr->pageno > o_pages(lu_ptr->file) ) {
- /* no need to rewrite this page at trcommit time */
- pg_ptr->holdcnt = 0;
- pg_ptr->modified = FALSE;
- --no_modheld;
- }
- continue;
- }
- pg_ptr->ovfl_addr = 0L;
-#endif
/* write directly to database */
-#ifdef NO_TRANS
#ifdef DEBUG_DIO
if (debugging_dio_close) {
printf (__FILE__"723 dio_flush: write modified pg#%d @ %p\n",
}
#endif
if (dio_out(pg_ptr, lu_ptr) != S_OKAY) return( db_status );
-#else
- if (dio_out(pg_ptr, lu_ptr, 1) != S_OKAY) return( db_status );
-#endif
pg_ptr->holdcnt = 0;
pg_ptr->modified = FALSE;
--no_modheld;
-#ifndef NO_TRANS
- if ( trlog_flag ) {
- fno = lu_ptr->file;
- MEM_LOCK(&pg_ptr->Buff);
- d_trlog(fno, (int)lu_ptr->pageno, pg_ptr->buff,
- file_table[fno].ft_pgsize);
- MEM_UNLOCK(&pg_ptr->Buff);
- }
-#endif
}
/* store the page zero values in the data file and return */
return( dio_pzflush() );
{
PAGE_ENTRY *pg_ptr;
-#ifndef NO_TRANS
- /* ensure overflow data is initialized when exclusive db access */
- if ((trans_id && (dboptions & TRLOGGING) && use_ovfl) &&
- (o_fileinit(working_file) != S_OKAY))
- return( db_status );
-#endif
#ifndef SINGLE_USER
if ( dbopen == 1 ) {
/* check shared access privileges */
file = NUM2INT((FILE_NO)((dba >> FILESHIFT) & FILEMASK), ft_offset);
-#ifndef NO_TRANS
- /* ensure overflow data is initialized when exclusive db access */
- if ((trans_id && (dboptions & TRLOGGING) && use_ovfl) &&
- (o_fileinit(file) != S_OKAY))
- return( db_status );
-#endif
#ifndef SINGLE_USER
if (dbopen == 1) {
if (!trans_id && !excl_locks[file])
PAGE_ENTRY *pg_ptr;
int *lru_ptr;
int pg_slot;
-#ifndef NO_TRANS
- BOOLEAN db_cache; /* TRUE if currently using dbpg_table */
- F_ADDR ovfl_addr;
-#endif
-#ifdef NO_TRANS
/* check if desired page was last one */
if ((file == last_dblu.file) && (page == last_dblu.pageno)) {
}
lookup = db_lookup;
pgtab_sz = db_pgtab_sz;
-#else /* NO_TRANS */
- if (db_cache = (!pg_table || (pg_table == dbpg_table))) {
- /* check if desired page was last one */
- if ((file == last_dblu.file) && (page == last_dblu.pageno)) {
- if (xlu_ptr != NULL)
- *xlu_ptr = &db_lookup[last_dblu.slot];
- if (xpg_ptr != NULL)
- *xpg_ptr = &dbpg_table[db_lookup[last_dblu.slot].pg_slot];
- return( db_status = S_OKAY );
- }
- lookup = db_lookup;
- pgtab_sz = db_pgtab_sz;
- }
- else {
- lookup = ix_lookup;
- pgtab_sz = ix_pgtab_sz;
- }
-#endif /* NO_TRANS */
/* perform binary search of sorted lookup table */
l = 0;
u = pgtab_sz - 1;
else if (cmp > 0)
l = lu_slot + 1;
else {
-#ifndef NO_TRANS
- if (db_cache)
- {
-#endif
last_dblu.file = lu_ptr->file;
last_dblu.pageno = lu_ptr->pageno;
last_dblu.slot = lu_slot;
-#ifndef NO_TRANS
- }
-#endif
if (xlu_ptr != NULL)
*xlu_ptr = lu_ptr;
if (xpg_ptr != NULL)
return( db_status = S_NOTFOUND );
}
/* page not found - read into cache */
-#ifndef NO_TRANS
- if( !use_ovfl && trans_id && (no_modheld == pgtab_sz) )
- return( db_status = S_TRCHANGES );
-
- /* check to see if page is in overflow file */
- ovfl_addr = 0L;
- if ( cache_ovfl && file != ov_file ) {
- if ( o_search( file, page, &ovfl_addr ) != S_OKAY )
- return( db_status );
- }
- /* check for overflow */
- if ( db_cache && trans_id && (no_modheld == pgtab_sz) && !cache_ovfl ) {
- cache_ovfl = TRUE;
- }
- /* select a page to replace */
- if (db_cache) {
- lru_ptr = &dbpg_lru_slot;
- } else {
- lru_ptr = &ixpg_lru_slot;
- }
-#else
/* select a page to replace */
lru_ptr = &dbpg_lru_slot;
-#endif /* NO_TRANS */
for (cnt = 2*pgtab_sz, pg_slot = *lru_ptr, pg_ptr = &pg_table[pg_slot];
--cnt >= 0;
++pg_slot, ++pg_ptr) {
}
replu_ptr = &lookup[pg_ptr->lu_slot];
if (!pg_ptr->recently_used && (pg_ptr->holdcnt == 0)) {
-#ifdef NO_TRANS
if (pg_ptr->modified) {
dio_out(pg_ptr, replu_ptr);
pg_ptr->modified = FALSE;
--no_modheld;
}
-#else
- if (pg_ptr->modified) {
- /* allow updates outside transactions for single-user mode */
-#ifdef SINGLE_USER
- if (!db_cache || (EXCL_OPEN() && !trans_id)) {
-#else
- if (!db_cache || ((EXCL_OPEN() ||
- excl_locks[lookup[pg_ptr->lu_slot].file]) && !trans_id)) {
-#endif /* SINGLE_USER */
- /* ix page swapping occurs here */
- dio_out(pg_ptr, replu_ptr, db_cache);
- pg_ptr->modified = FALSE;
- if ( db_cache ) --no_modheld;
- }
- else {
- if (!use_ovfl || !cache_ovfl) continue; /* skip modified pages */
- /* Write out modified page */
- pg_ptr->modified = FALSE;
- --no_modheld; /* must be in db cache */
- if (o_write(pg_ptr, replu_ptr) != S_OKAY) return( db_status );
- }
- }
- pg_ptr->ovfl_addr = ovfl_addr;
-#endif /* NO_TRANS */
pg_ptr->recently_used = TRUE;
if ((*lru_ptr = (pg_slot + 1)) >= pgtab_sz)
*lru_ptr = 0;
*xlu_ptr = lu_ptr;
if (xpg_ptr != NULL)
*xpg_ptr = pg_ptr;
-#ifdef NO_TRANS
last_dblu.file = lu_ptr->file;
last_dblu.pageno = lu_ptr->pageno;
last_dblu.slot = lu_slot;
dio_in(pg_ptr, lu_ptr);
-#else
- if (db_cache) {
- last_dblu.file = lu_ptr->file;
- last_dblu.pageno = lu_ptr->pageno;
- last_dblu.slot = lu_slot;
- }
- dio_in(pg_ptr, lu_ptr, db_cache);
-#endif
return( db_status );
#undef tempbuff
* page swap function.
*/
int
-#ifndef NO_TRANS
-dio_out(pg_ptr, lu_ptr, db_cache)
-#else
dio_out(pg_ptr, lu_ptr)
-#endif
PAGE_ENTRY *pg_ptr; /* page table entry to be output */
LOOKUP_ENTRY *lu_ptr; /* corresponding lookup table entry */
-#ifndef NO_TRANS
- BOOLEAN db_cache; /* TRUE if pg_ptr is in db page cache */
-#endif
{
int desc; /* file descriptor */
int fno; /* file number */
netorder_timestamp = (ULONG) host_timestamp;
HTONL (netorder_timestamp);
-#ifdef NO_TRANS
fno = lu_ptr->file;
pgsize = file_table[fno].ft_pgsize;
addr = lu_ptr->pageno * (long)pgsize;
memcpy (pg_ptr->buff, &netorder_timestamp, sizeof(ULONG));
-#else
- if ( db_cache ) {
- fno = lu_ptr->file;
- pgsize = file_table[fno].ft_pgsize;
- }
- else
- pgsize = file_table[ov_file].ft_pgsize;
-
- if ( pg_ptr->ovfl_addr == 0L ) {
- /* write to database */
- addr = lu_ptr->pageno * (long)pgsize;
- memcpy (pg_ptr->buff, &netorder_timestamp, sizeof(ULONG));
- }
- else {
- /* write to overflow file */
- fno = ov_file;
- addr = pg_ptr->ovfl_addr;
- }
-#endif
if ( dio_open(fno) == S_OKAY ) {
swab_page (pg_ptr->buff, &file_table[fno], HTON);
desc = file_table[fno].ft_desc;
/* dio_in */
/* */
/****************************************/
-#ifdef NO_TRANS
/* Read in a page to the buffer
*/
static int dio_in(pg_ptr, lu_ptr)
PAGE_ENTRY *pg_ptr; /* page table entry to be input */
LOOKUP_ENTRY *lu_ptr; /* corresponding to pg_ptr */
-#else
-/* Read in a page to the buffer
-*/
-static int dio_in(pg_ptr, lu_ptr, db_cache )
-PAGE_ENTRY *pg_ptr; /* page table entry to be input */
-LOOKUP_ENTRY *lu_ptr; /* corresponding to pg_ptr */
-BOOLEAN db_cache; /* TRUE if pg_ptr in db cache */
-#endif
{
int desc; /* file descriptor */
int fno; /* file number */
int r;
file_ptr = &file_table[fno = lu_ptr->file];
-#ifdef NO_TRANS
pgsize = file_ptr->ft_pgsize;
addr = lu_ptr->pageno*pgsize;
-#else
- pgsize = db_cache ? file_ptr->ft_pgsize : file_table[ov_file].ft_pgsize;
-
- if (pg_ptr->ovfl_addr == 0L) {
- /* read from database file */
- /* if !db_cache, overflow address not set on initial read */
- addr = db_cache ? lu_ptr->pageno*pgsize :
- (pg_ptr->ovfl_addr = lu_ptr->pageno);
- }
- else {
- /* read from overflow file */
- file_ptr = &file_table[fno = ov_file];
- addr = pg_ptr->ovfl_addr;
- }
-#endif
if ( dio_open(fno) == S_OKAY ) {
desc = file_ptr->ft_desc;
DB_LSEEK(desc, (off_t)addr, 0);
char *cptr;
int j;
-#ifndef NO_TRANS
- if ( (dboptions & TRLOGGING) && trans_id && !trcommit && use_ovfl ) {
- /* flush to overflow/log file -- before tx commit */
- for (i = 0, pgzero_ptr = pgzero; i < size_ft; ++i, ++pgzero_ptr) {
- if (pgzero_ptr->pz_modified )
- if ( o_pzwrite( i ) != S_OKAY ) return( db_status );
- }
- }
- else {
-#endif
/* flush modified page zeroes to database files */
for (i = 0, pgzero_ptr = pgzero, file_ptr = file_table; i < size_ft;
++i, ++pgzero_ptr, ++file_ptr) {
if (DB_WRITE(desc, (char *)pgzero_ptr, PGZEROSZ) != PGZEROSZ)
return( dberr(S_BADWRITE) );
pgzero_ptr->pz_modified = FALSE;
-#ifndef NO_TRANS
- if ( trlog_flag )
- d_trlog(i, 0, (char *)pgzero_ptr, PGZEROSZ);
-#endif
}
#ifdef CLOSE_FILES
dio_close(i);
#endif
}
-#ifndef NO_TRANS
- }
-#endif
return( db_status = S_OKAY );
} /* dio_pzflush() */