185 lines
5.3 KiB
C
185 lines
5.3 KiB
C
|
/* JET API flags
|
||
|
/**/
|
||
|
#define FPIBVersion( ppib ) (!((ppib)->grbit & (JET_bitCIMCommitted | JET_bitCIMDirty)))
|
||
|
#define FPIBCommitted( ppib ) ((ppib)->grbit & JET_bitCIMCommitted)
|
||
|
#define FPIBDirty( ppib ) ((ppib)->grbit & JET_bitCIMDirty)
|
||
|
#define FPIBAggregateTransaction( ppib ) ((ppib)->grbit & JET_bitAggregateTransaction)
|
||
|
#define FPIBBMClean( ppib ) ((ppib)->fBMCleanProc )
|
||
|
#define PIBSetBMClean( ppib ) ((ppib)->fBMCleanProc = 1 )
|
||
|
#define PIBResetBMClean( ppib ) ((ppib)->fBMCleanProc = 0 )
|
||
|
|
||
|
//
|
||
|
// Process Information Block
|
||
|
//
|
||
|
struct _pib
|
||
|
{
|
||
|
/* most used field has offset 0
|
||
|
/**/
|
||
|
TRX trxBegin0; // trx id
|
||
|
TRX trxCommit0;
|
||
|
|
||
|
/* JET API fields
|
||
|
/**/
|
||
|
JET_SESID sesid; // JET session id
|
||
|
JET_GRBIT grbit; // session flags
|
||
|
|
||
|
struct _pib *ppibNext; // PIB list
|
||
|
LEVEL level; // transaction level of this session
|
||
|
LEVEL levelRollback; // transaction level which must be rolled back
|
||
|
struct _dab *pdabList; // list of open DAB's of this thread
|
||
|
USHORT rgcdbOpen[dbidMax]; // counter for open databases
|
||
|
struct _fucb *pfucb; // list of active fucb of this thread
|
||
|
|
||
|
/* logging/recovery fields
|
||
|
/**/
|
||
|
PROCID procid; // thread id
|
||
|
LGPOS lgposStart; // log time
|
||
|
LEVEL levelBegin; // transaction level when first begin transaction operation
|
||
|
LEVEL levelDeferBegin; // count of deferred open transactions
|
||
|
SIG sigWaitLogFlush;
|
||
|
LONG lWaitLogFlush;
|
||
|
LONG grbitsCommitDefault;
|
||
|
struct _pib *ppibNextWaitFlush;
|
||
|
struct _pib *ppibPrevWaitFlush;
|
||
|
LGPOS lgposPrecommit0; // level 0 precommit record position.
|
||
|
|
||
|
/* flags
|
||
|
/**/
|
||
|
BOOL fUserSession:1; // user session
|
||
|
BOOL fAfterFirstBT:1; // for redo only
|
||
|
BOOL fLGWaiting:1; // waiting for log to flush
|
||
|
BOOL fBMCleanProc:1; // session is for doing BMCleanup
|
||
|
// BOOL fDeferFreeNodeSpace:1; // session has deferred node free space
|
||
|
BOOL fPrecommit:1; // in precommit state? Recovery only
|
||
|
BOOL fBegin0Logged:1; // begin transaction has logged
|
||
|
BOOL fSetAttachDB:1; // set up attachdb.
|
||
|
|
||
|
BOOL fMacroGoing:1;
|
||
|
BOOL levelMacro:4;
|
||
|
|
||
|
/* version store fields
|
||
|
/**/
|
||
|
RCE *prceNewest; // newest RCE of session
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
DWORD dwLogThreadId;
|
||
|
#endif
|
||
|
|
||
|
/* counters for the session.
|
||
|
*/
|
||
|
LONG cAccessPage; // counter of page access.
|
||
|
LONG cLatchConflict; // counter of page latch conflicts.
|
||
|
LONG cSplitRetry; // counter of split retries.
|
||
|
LONG cNeighborPageScanned; // counter of neighboring page scanned.
|
||
|
|
||
|
union {
|
||
|
struct { // Redo only.
|
||
|
BYTE *rgbLogRec;
|
||
|
WORD cbLogRecMac;
|
||
|
WORD ibLogRecAvail;
|
||
|
};
|
||
|
|
||
|
struct { // Do only
|
||
|
/* array for internal macro operations.
|
||
|
*/
|
||
|
struct _bf **rgpbfLatched; // dynamically allocated array
|
||
|
WORD cpbfLatchedMac; // for macro operations.
|
||
|
WORD ipbfLatchedAvail; // for macro operations.
|
||
|
};
|
||
|
};
|
||
|
|
||
|
#ifdef PCACHE_OPTIMIZATION
|
||
|
/* pad to multiple of 32 bytes
|
||
|
/**/
|
||
|
#ifdef DEBUG
|
||
|
BYTE rgbFiller[0];
|
||
|
#else
|
||
|
BYTE rgbFiller[4];
|
||
|
#endif
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
#define PpibMEMAlloc() (PIB*)PbMEMAlloc(iresPIB)
|
||
|
|
||
|
#ifdef DEBUG /* Debug check for illegal use of freed pib */
|
||
|
#define MEMReleasePpib(ppib) { MEMRelease(iresPIB, (BYTE*)(ppib)); ppib = ppibNil; }
|
||
|
#else
|
||
|
#define MEMReleasePpib(ppib) { MEMRelease(iresPIB, (BYTE*)(ppib)); }
|
||
|
#endif
|
||
|
|
||
|
extern PIB *ppibGlobal;
|
||
|
extern PIB *ppibGlobalMin;
|
||
|
extern PIB *ppibGlobalMax;
|
||
|
|
||
|
PROCID ProcidPIBOfPpib( PIB *ppib );
|
||
|
|
||
|
STATIC INLINE PROCID ProcidPIBOfPpib( PIB *ppib )
|
||
|
{
|
||
|
return (PROCID)(((BYTE *)ppib - (BYTE *)ppibGlobalMin)/sizeof(PIB));
|
||
|
}
|
||
|
|
||
|
STATIC INLINE PIB *PpibOfProcid( PROCID procid )
|
||
|
{
|
||
|
return ppibGlobalMin + procid;
|
||
|
}
|
||
|
|
||
|
/* PIB validation
|
||
|
/**/
|
||
|
#define ErrPIBCheck( ppib ) \
|
||
|
( ( ppib >= ppibGlobalMin \
|
||
|
&& ppib < ppibGlobalMax \
|
||
|
&& ( ( (BYTE *)ppib - (BYTE *)ppibGlobalMin ) % sizeof(PIB) ) == 0 \
|
||
|
&& ppib->procid == ProcidPIBOfPpib( ppib ) ) \
|
||
|
? JET_errSuccess : JET_errInvalidSesid )
|
||
|
|
||
|
#define CheckPIB( ppib ) \
|
||
|
Assert( ErrPIBCheck( ppib ) == JET_errSuccess \
|
||
|
&& (ppib)->level < levelMax )
|
||
|
|
||
|
#if 0
|
||
|
#define FPIBDeferFreeNodeSpace( ppib ) ( (ppib)->fDeferFreeNodeSpace )
|
||
|
#define PIBSetDeferFreeNodeSpace( ppib ) ( (ppib)->fDeferFreeNodeSpace = fTrue )
|
||
|
#define PIBResetDeferFreeNodeSpace( ppib ) ( (ppib)->fDeferFreeNodeSpace = fFalse )
|
||
|
#endif
|
||
|
|
||
|
#define FPIBActive( ppib ) ( (ppib)->level != levelNil )
|
||
|
|
||
|
#define SesidOfPib( ppib ) ( (ppib)->sesid )
|
||
|
|
||
|
/* prototypes
|
||
|
/**/
|
||
|
LONG CppibPIBUserSessions( VOID );
|
||
|
VOID RecalcTrxOldest( );
|
||
|
ERR ErrPIBBeginSession( PIB **pppib, PROCID procid );
|
||
|
VOID PIBEndSession( PIB *ppib );
|
||
|
#ifdef DEBUG
|
||
|
VOID PIBPurge( VOID );
|
||
|
#else
|
||
|
#define PIBPurge()
|
||
|
#endif
|
||
|
|
||
|
#define PIBUpdatePrceNewest( ppib, prce ) \
|
||
|
{ \
|
||
|
if ( (ppib)->prceNewest == (prce) ) \
|
||
|
{ \
|
||
|
Assert( (prce)->prceNextOfSession == prceNil ); \
|
||
|
(ppib)->prceNewest = prceNil; \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
#define PIBSetPrceNewest( ppib, prce ) \
|
||
|
{ \
|
||
|
(ppib)->prceNewest = (prce); \
|
||
|
}
|
||
|
|
||
|
|
||
|
#define PIBSetLevelRollback( ppib, levelT ) \
|
||
|
{ \
|
||
|
Assert( (levelT) > levelMin && \
|
||
|
(levelT) < levelMax ); \
|
||
|
Assert( (ppib)->levelRollback >= levelMin && \
|
||
|
(ppib)->levelRollback < levelMax ); \
|
||
|
if ( levelT < (ppib)->levelRollback ) \
|
||
|
(ppib)->levelRollback = (levelT); \
|
||
|
}
|