Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

261 lines
9.7 KiB

//============== DAE: OS/2 Database Access Engine ===================
//============== fcb.h: File Control Block ===================
#ifdef FCB_INCLUDED
#error fcb.h already included
#endif /* FCB_INCLUDED */
#define FCB_INCLUDED
// Database Key
typedef ULONG DBK;
// Flags for FCB
#define fFCBTemporaryTable (1<<0) // This is a temporary file
#define fFCBClusteredIndex (1<<1) // This FCB is for data records.
#define fFCBDenyRead (1<<2) // no other session can read domain
// #define fFCBDenyWrite (1<<3) // no other session can write domain
#define fFCBSentinel (1<<4) // FCB is only flag holder
// #define fFCBDenyDDL (1<<5) // no other transaction can update/delete/replace domain
#define fFCBWait (1<<6) // wait flag
#define fFCBOLCStatsAvail (1<<7) // are OLC Stats available?
#define fFCBOLCStatsChange (1<<8) // have OLC Stats changed since last open?
#define fFCBDeletePending (1<<9) // is a delete pending on this table/index?
#define fFCBDomainOperation (1<<10) // is used to synchronize bm cleanup
// index creation, index deletion and table deletion
#define FFCBDomainOperation( pfcb ) ( (pfcb)->wFlags & fFCBDomainOperation )
#define FCBSetDomainOperation( pfcb ) ( (pfcb)->wFlags |= fFCBDomainOperation )
#define FCBResetDomainOperation( pfcb ) ( (pfcb)->wFlags &= ~(fFCBDomainOperation) )
#define FFCBDeletePending( pfcb ) ( (pfcb)->wFlags & fFCBDeletePending )
#define FCBSetDeletePending( pfcb ) ( (pfcb)->wFlags |= fFCBDeletePending )
#define FCBResetDeletePending( pfcb ) ( (pfcb)->wFlags &= ~(fFCBDeletePending) )
#define FFCBOLCStatsAvail( pfcb ) ( (pfcb)->wFlags & fFCBOLCStatsAvail )
#define FCBSetOLCStatsAvail( pfcb ) ( (pfcb)->wFlags |= fFCBOLCStatsAvail )
#define FCBResetOLCStatsAvail( pfcb ) ( (pfcb)->wFlags &= ~(fFCBOLCStatsAvail) )
#define FFCBOLCStatsChange( pfcb ) ( (pfcb)->wFlags & fFCBOLCStatsChange )
#define FCBSetOLCStatsChange( pfcb ) ( (pfcb)->wFlags |= fFCBOLCStatsChange )
#define FCBResetOLCStatsChange( pfcb ) ( (pfcb)->wFlags &= ~(fFCBOLCStatsChange) )
#define FFCBTemporaryTable( pfcb ) ( (pfcb)->wFlags & fFCBTemporaryTable )
#define FCBSetTemporaryTable( pfcb ) ( (pfcb)->wFlags |= fFCBTemporaryTable )
#define FCBResetTemporaryTable( pfcb ) ( (pfcb)->wFlags &= ~(fFCBTemporaryTable) )
#define FFCBClusteredIndex( pfcb ) ( (pfcb)->wFlags & fFCBClusteredIndex )
#define FCBSetClusteredIndex( pfcb ) ( (pfcb)->wFlags |= fFCBClusteredIndex )
#define FCBResetClusteredIndex( pfcb ) ( (pfcb)->wFlags &= ~(fFCBClusteredIndex) )
#define FFCBDenyWrite( pfcb ) ( (pfcb)->crefDenyWrite > 0 )
#define FCBSetDenyWrite( pfcb ) ( (pfcb)->crefDenyWrite++ )
#define FCBResetDenyWrite( pfcb ) \
{ \
Assert( (pfcb)->crefDenyWrite > 0 ); \
--(pfcb)->crefDenyWrite; \
}
#define FFCBDenyRead( pfcb, ppib ) ( (pfcb)->wFlags & fFCBDenyRead && (ppib) != (pfcb)->ppibDenyRead )
#define FCBSetDenyRead( pfcb, ppib ) \
{ \
if ( (pfcb)->crefDenyRead++ == 0 ) \
{ \
Assert( (pfcb)->ppibDenyRead == ppibNil ); \
(pfcb)->ppibDenyRead = (ppib); \
(pfcb)->wFlags |= fFCBDenyRead; \
} \
}
#define FCBResetDenyRead( pfcb ) \
{ \
Assert( (pfcb)->crefDenyRead > 0 ); \
Assert( (pfcb)->ppibDenyRead != ppibNil ); \
if ( --(pfcb)->crefDenyRead == 0 ) \
{ \
(pfcb)->wFlags &= ~(fFCBDenyRead); \
(pfcb)->ppibDenyRead = ppibNil; \
} \
}
#define FFCBDenyReadByUs( pfcb, ppib ) ( (pfcb)->wFlags & fFCBDenyRead && (ppib) == (pfcb)->ppibDenyRead )
#define FFCBSentinel( pfcb ) ( (pfcb)->wFlags & fFCBSentinel )
#define FCBSetSentinel( pfcb ) ( (pfcb)->wFlags |= fFCBSentinel )
#define FCBResetSentinel( pfcb ) ( (pfcb)->wFlags &= ~(fFCBSentinel) )
#define FFCBDenyDDL( pfcb, ppib ) ( (pfcb)->crefDenyDDL > 0 && (ppib) != (pfcb)->ppibDDL )
#define FFCBDenyDDLByUs( pfcb, ppib ) ( (pfcb)->crefDenyDDL > 0 && (ppib) == (pfcb)->ppibDDL )
#define FCBSetDenyDDL( pfcb, ppib ) \
{ \
if ( (pfcb)->crefDenyDDL++ == 0 ) \
{ \
Assert( (pfcb)->ppibDDL == ppibNil ); \
(pfcb)->ppibDDL = (ppib); \
} \
}
#define FCBResetDenyDDL( pfcb ) \
{ \
Assert( (pfcb)->crefDenyDDL > 0 ); \
Assert( (pfcb)->ppibDDL != ppibNil ); \
if ( --(pfcb)->crefDenyDDL == 0 ) \
{ \
(pfcb)->ppibDDL = ppibNil; \
} \
}
#define FFCBWait( pfcb ) ( (pfcb)->wFlags & fFCBWait )
#define FCBSetWait( pfcb ) \
{ \
Assert( !FFCBWait( pfcb ) ); \
(pfcb)->wFlags |= fFCBWait; \
}
#define FCBResetWait( pfcb ) \
{ \
Assert( FFCBWait( pfcb ) ); \
(pfcb)->wFlags &= ~(fFCBWait); \
}
#define FCBVersionIncrement( pfcb ) (pfcb)->cVersion++;
#define FCBVersionDecrement( pfcb ) \
{ \
Assert( (pfcb)->cVersion > 0 ); \
(pfcb)->cVersion--; \
}
#define CVersionFCB( pfcb ) (pfcb)->cVersion
/* hash table for FCB's -- only FCB's for tables and db's are hashed
/**/
#define cFCBBuckets 256
FCB* pfcbHash[cFCBBuckets];
#define FCBHashInit() \
{ \
Assert( pfcbNil == (FCB *) 0 ); \
memset( pfcbHash, '\0', sizeof( pfcbHash ) ); \
}
#define FFCBAvail( pfcb, ppib ) \
( pfcb->wRefCnt == 0 && \
pfcb->pgnoFDP != 1 && \
!FFCBSentinel( pfcb ) && \
!FFCBDenyRead( pfcb, ppib ) && \
!FFCBWait( pfcb ) && \
( pfcb->dbid == dbidTemp || FFCBINoVersion( pfcb ) ) )
// File Control Block
//
struct _fcb
{
//--------------------USED BY DATA & INDEX FCB---------------------
struct _fcb *pfcbNextIndex; // chain of indexes for this file
struct _fcb *pfcbNextInHashBucket;
struct _fdb volatile *pfdb; // field descriptors
struct _idb *pidb; // index info (NULL if "seq." file)
FUCB *pfucb; // chain of FUCBs open on this file
PIB *ppibDDL; // ppib of process updating index/adding column
PIB *ppibDenyRead; // ppib of process holding exclusive lock
CRIT critSplit; // per domain split MUTEX
PGNO pgnoFDP; // FDP of this file/index
PGNO pgnoRoot; // pgno of the root of the domain
SRID bmRoot; // bm of root of the domain
// -- useful if Root is movable, e.g, DATA
DBID dbid; // which database
INT itagRoot; // itag of the root of the domain
INT cbDensityFree; // loading density parameter:
// # of bytes free w/o using new page
INT wFlags; // flags for this FCB
INT wRefCnt; // # of FUCBs for this file/index
INT volatile cVersion; // # of RCEs for this file/index
INT crefDenyRead; // # of FUCBs with deny read flag
INT crefDenyWrite; // # of FUCBs with deny write flag
INT crefDenyDDL; // # of FUCBs with deny DDL flag
ULONG cpgCompactFreed;
PERS_OLCSTAT olcStat;
//--------------------USED ONLY BY FCB OF DATA---------------------
CHAR *szFileName; // name of file (for GetTableInfo)
struct _fcb *pfcbNext; // Next data FCB in global list
DBK dbkMost; // Greatest DBK in use
// (if "sequential" file)
ULONG ulLongIdMax; // max long field id
BYTE rgbitAllIndex[32]; // used for clustered index FCB only
BOOL fAllIndexTagged; // used for clustered index FCB only
};
#define FCBInit( pfcb ) \
{ \
memset( pfcb, '\0', sizeof( FCB ) ); \
}
#define PfcbMEMAlloc() (FCB*)PbMEMAlloc(iresFCB)
#ifdef DEBUG /* Debug check for illegal use of freed fcb */
#define MEMReleasePfcb(pfcb) \
{ \
Assert( PfcbFCBGet( pfcb->dbid, pfcb->pgnoFDP ) != pfcb ); \
MEMRelease( iresFCB, (BYTE*)(pfcb) ); \
pfcb = pfcbNil; \
}
#else
#define MEMReleasePfcb(pfcb) \
{ \
Assert( PfcbFCBGet( pfcb->dbid, pfcb->pgnoFDP ) != pfcb ); \
MEMRelease( iresFCB, (BYTE*)(pfcb) ); \
}
#endif
/* if opening domain for read, write or read write, and not with
/* deny read or deny write, and domain does not have deny read or
/* deny write set, then return JET_errSuccess, else call
/* ErrFCBISetMode to determine if lock is by other session or to
/* put lock on domain.
/**/
#define ErrFCBSetMode( ppib, pfcb, grbit ) \
( ( ( ( grbit & ( JET_bitTableDenyRead | JET_bitTableDenyWrite ) ) == 0 ) && \
( ( FFCBDenyDDL( pfcb, ppib ) || FFCBDenyRead( pfcb, ppib ) || FFCBDenyWrite( pfcb ) ) == fFalse ) ) ? \
JET_errSuccess : ErrFCBISetMode( ppib, pfcb, grbit ) )
/* reset DDL is same as reset Delete. Both use deny read flags
/* or sentinel.
/**/
#define FCBResetRenameTable FCBResetDeleteTable
extern BYTE * __near rgfcb;
extern FCB * __near pfcbGlobalList;
extern SEM __near semGlobalFCBList;
extern SEM __near semLinkUnlink;
VOID FCBLink( FUCB *pfucb, FCB *pfcb );
VOID FCBRegister( FCB *pfcb );
VOID FCBDiscard( FCB *pfcb );
VOID FCBUnlink( FUCB *pfucb );
FCB *PfcbFCBGet( DBID dbid, PGNO pgnoFDP );
ERR ErrFCBAlloc( PIB *ppib, FCB **ppfcb );
VOID FCBPurgeDatabase( DBID dbid );
VOID FCBPurgeTable( DBID dbid, PGNO pgnoFDP );
ERR ErrFCBNew( PIB *ppib, DBID dbid, PGNO pgno, FCB **ppfcb );
ERR ErrFCBISetMode( PIB *ppib, FCB *pfcb, JET_GRBIT grbit );
VOID FCBResetMode( PIB *ppib, FCB *pfcb, JET_GRBIT grbit );
ERR ErrFCBSetDeleteTable( PIB *ppib, DBID dbid, PGNO pgnoFDP );
VOID FCBResetDeleteTable( DBID dbid, PGNO pgnoFDP );
ERR ErrFCBSetRenameTable( PIB *ppib, DBID dbid, PGNO pgno );
FCB *FCBResetAfterRedo( void );
BOOL FFCBTableOpen ( DBID dbid, PGNO pgno );
VOID FCBLinkIndex( FCB *pfcbTable, FCB *pfcbIndex );
VOID FCBUnlinkIndex( FCB *pfcbTable, FCB *pfcbIndex );
BOOL FFCBUnlinkIndexIfFound( FCB *pfcbTable, FCB *pfcbIndex );
FCB *PfcbFCBUnlinkIndexByName( FCB *pfcb, CHAR *szIndex );
ERR ErrFCBSetDeleteIndex( PIB *ppib, FCB *pfcbTable, CHAR *szIndex );
VOID FCBResetDeleteIndex( FCB *pfcbIndex );