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.
449 lines
14 KiB
449 lines
14 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1998.
|
|
//
|
|
// File: wqcache.hxx
|
|
//
|
|
// Contents: WEB Query cache class
|
|
//
|
|
// History: 96/Jan/3 DwightKr Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CWQueryBookmark
|
|
//
|
|
// Purpose: A bookmark to a specific query
|
|
//
|
|
// History: 96/Jan/23 DwightKr Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
const unsigned cchBookmark = (5+16+8+8); // N-xxxx-xxx-xxx
|
|
|
|
class CWQueryBookmark
|
|
{
|
|
public:
|
|
CWQueryBookmark( WCHAR const * wcsBookmark );
|
|
CWQueryBookmark( BOOL fSequential,
|
|
CWQueryItem * pItem,
|
|
ULONG ulSequenceNumber,
|
|
LONG lRecordNumber );
|
|
|
|
BOOL IsSequential() const { return _fSequential; }
|
|
|
|
ULONG GetSequenceNumber() const { return _ulSequenceNumber; }
|
|
|
|
CWQueryItem const * GetQueryItem() const { return _pItem; }
|
|
|
|
LONG GetRecordNumber() const { return _lRecordNumber; }
|
|
|
|
WCHAR const * GetBookmark() const { return _wcsBookmark; }
|
|
|
|
private:
|
|
BOOL _fSequential; // Is this a sequential cursor
|
|
CWQueryItem * _pItem; // Address of a query item
|
|
ULONG _ulSequenceNumber; // Unique sequence number
|
|
LONG _lRecordNumber; // Record number
|
|
WCHAR _wcsBookmark[cchBookmark]; // String rep of bookmark
|
|
};
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CWQueryCache
|
|
//
|
|
// Purpose: A list of cached queries
|
|
//
|
|
// History: 96/Jan/23 DwightKr Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CWQueryCache : public CDoubleList
|
|
{
|
|
public:
|
|
CWQueryCache();
|
|
~CWQueryCache();
|
|
|
|
CWQueryItem * CreateOrFindQuery( WCHAR const * wcsIDQFile,
|
|
XPtr<CVariableSet> & variableSet,
|
|
XPtr<COutputFormat> & outputFormat,
|
|
CSecurityIdentity securityIdentity,
|
|
BOOL & fAsynchronous );
|
|
void DeleteOldQueries();
|
|
|
|
|
|
void Release( CWQueryItem * pItem, BOOL fDecRunningQueries = TRUE );
|
|
|
|
#if (DBG == 1)
|
|
BOOL Internal( CVariableSet & variableSet,
|
|
COutputFormat & outputFormat,
|
|
CVirtualString & string );
|
|
#endif // DBG == 1
|
|
|
|
void FlushCache();
|
|
|
|
void AddToCache( CWQueryItem * pItem );
|
|
|
|
BOOL AddToPendingRequestQueue( EXTENSION_CONTROL_BLOCK *pEcb );
|
|
|
|
void Shutdown();
|
|
|
|
void Wakeup()
|
|
{
|
|
_eventCacheWork.Set(); // wake up thread
|
|
}
|
|
|
|
void IncrementActiveRequests()
|
|
{
|
|
long x = InterlockedIncrement( & _cActiveRequests );
|
|
Win4Assert( 0 != x );
|
|
}
|
|
|
|
void DecrementActiveRequests()
|
|
{
|
|
long x = InterlockedDecrement( & _cActiveRequests );
|
|
Win4Assert( 0xffffffff != x );
|
|
}
|
|
|
|
void IncrementRejectedRequests()
|
|
{
|
|
InterlockedIncrement( & _cRequestsRejected );
|
|
*_pcRequestsRejected = _cRequestsRejected;
|
|
}
|
|
|
|
void UpdatePendingRequestCount();
|
|
|
|
//
|
|
// State
|
|
//
|
|
|
|
ULONG Percent(ULONG num, ULONG den)
|
|
{ return (den == 0) ? 0:
|
|
(ULONG)((((ULONGLONG) num * 100) + (den/2) ) / den); }
|
|
|
|
ULONG Hits() { return Percent(*_pcCacheHits, *_pcCacheHitsAndMisses); }
|
|
ULONG Misses() { return Percent(*_pcCacheMisses, *_pcCacheHitsAndMisses); }
|
|
ULONG Running() { return *_pcRunningQueries; }
|
|
ULONG Cached() { return *_pcCacheItems; }
|
|
ULONG Rejected() { return *_pcRequestsRejected; }
|
|
ULONG Total() { return *_pcTotalQueries; }
|
|
ULONG QPM() { return *_pcQueriesPerMinute; }
|
|
|
|
LONG ActiveRequestCount() { return _cActiveRequests; }
|
|
unsigned PendingQueryCount() { return _pendingQueue.Count(); }
|
|
|
|
private:
|
|
|
|
ULONG GetNextSequenceNumber()
|
|
{
|
|
InterlockedIncrement( (LONG *) &_ulSequenceNumber );
|
|
|
|
return _ulSequenceNumber;
|
|
}
|
|
|
|
ULONG GetSequenceNumber()
|
|
{
|
|
return _ulSequenceNumber;
|
|
}
|
|
|
|
CWQueryItem * FindItem( CWQueryBookmark & bookmark,
|
|
LONG lSkipCount,
|
|
CSecurityIdentity securityIdentity );
|
|
|
|
CWQueryItem * FindItem( XPtr<CVariableSet> & variableSet,
|
|
XPtr<COutputFormat> & outputFormat,
|
|
WCHAR const * wcsIDQFile,
|
|
CSecurityIdentity securityIdentity );
|
|
|
|
CWQueryItem * CreateNewQuery( WCHAR const * wcsIDQFile,
|
|
XPtr<CVariableSet> & variableSet,
|
|
XPtr<COutputFormat> & outputFormat,
|
|
CSecurityIdentity securityIdentity,
|
|
BOOL & fAsynchronous );
|
|
|
|
CWQueryItem * Pop() { return (CWQueryItem *) _Pop(); }
|
|
void Push(CWQueryItem * pItem) { _Push( pItem ); }
|
|
|
|
void LokMoveToFront( CWQueryItem * pItem );
|
|
|
|
static DWORD WINAPI WatchDogThread( void *self );
|
|
void ProcessCacheEvents();
|
|
|
|
BOOL CheckForCompletedQueries();
|
|
|
|
BOOL CheckForPendingRequests();
|
|
|
|
void IncrementRunningQueries()
|
|
{
|
|
long x = InterlockedIncrement( (LONG *)_pcRunningQueries );
|
|
|
|
// underflow check
|
|
Win4Assert( 0 != x );
|
|
}
|
|
|
|
void DecrementRunningQueries()
|
|
{
|
|
long x = InterlockedDecrement( (LONG *)_pcRunningQueries );
|
|
|
|
// underflow check
|
|
Win4Assert( 0xffffffff != x );
|
|
}
|
|
|
|
void Remove( CWQueryItem * pItem );
|
|
|
|
#if (DBG == 1)
|
|
void Dump( CVirtualString & string,
|
|
CVariableSet & variableSet,
|
|
COutputFormat & outputFormat );
|
|
#endif // DBG == 1
|
|
|
|
|
|
ULONG _ulSignature; // Signature of start of privates
|
|
ULONG _ulSequenceNumber; // Sequence # of each query issued
|
|
ULONG * _pcCacheItems; // Number of items in cache
|
|
ULONG * _pcCacheHits; // Number of cache hits
|
|
ULONG * _pcCacheMisses; // Number of cache misses
|
|
ULONG * _pcCacheHitsAndMisses; // Sum of hits and misses
|
|
ULONG * _pcRunningQueries; // Number of running queries
|
|
ULONG * _pcTotalQueries; // Number of new queries
|
|
ULONG * _pcRequestsQueued; // current # of queued requests
|
|
ULONG * _pcRequestsRejected; // total # of rejected requests
|
|
ULONG * _pcQueriesPerMinute; // Queries / min. ~15 second average.
|
|
LONG _cActiveRequests; // current # of active isapi requests
|
|
LONG _cRequestsRejected; // total # of rejected isapi requests
|
|
CMutexSem _mutex; // To serialize access to list
|
|
CMutexSem _mutexShutdown; // To serialize access to shutdowns
|
|
CEventSem _eventCacheWork; // Wakeup when time do work
|
|
CThread _threadWatchDog; // Cache watch dog thread
|
|
CIDQFileList _idqFileList; // Cache of parsed idq files
|
|
CHTXFileList _htxFileList; // Cache of parsed htx files
|
|
CDynArrayInPlace<CWPendingQueryItem *> _pendingQueue;
|
|
CNamedSharedMem _smPerf; // Shared memory for perf counters
|
|
|
|
//
|
|
// The "fake" perfcounters to shadow the real ones
|
|
//
|
|
|
|
CI_ISAPI_COUNTERS _smSpare;
|
|
};
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CWQueryCacheForwardIter
|
|
//
|
|
// Purpose: Iterates forward over a CWQueryCache
|
|
//
|
|
// History: 96/Jan/23 DwightKr Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
class CWQueryCacheForwardIter : public CForwardIter
|
|
{
|
|
public:
|
|
|
|
CWQueryCacheForwardIter( CWQueryCache & list ) : CForwardIter(list) {}
|
|
|
|
CWQueryItem * operator->() { return (CWQueryItem *) _pLinkCur; }
|
|
CWQueryItem * Get() { return (CWQueryItem *) _pLinkCur; }
|
|
};
|
|
|
|
|
|
void SetupDefaultCiVariables( CVariableSet & variableSet );
|
|
void SetupDefaultISAPIVariables( CVariableSet & variableSet );
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CWQueryCacheBackwardIter
|
|
//
|
|
// Purpose: Iterates backwards over a CWQueryCache
|
|
//
|
|
// History: 96/Jan/23 DwightKr Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
class CWQueryCacheBackwardIter : public CBackwardIter
|
|
{
|
|
public:
|
|
|
|
CWQueryCacheBackwardIter( CWQueryCache & list ) : CBackwardIter(list) {}
|
|
|
|
CWQueryItem * operator->() { return (CWQueryItem *) _pLinkCur; }
|
|
CWQueryItem * Get() { return (CWQueryItem *) _pLinkCur; }
|
|
};
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CICommandItem
|
|
//
|
|
// Purpose: Info for an ICommand cache entry
|
|
//
|
|
// History: 97/Feb/23 dlee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CICommandItem
|
|
{
|
|
public:
|
|
BOOL fInUse;
|
|
XInterface<ICommand> xCommand;
|
|
DWORD depth;
|
|
XArray<WCHAR> aMachine;
|
|
XArray<WCHAR> aCatalog;
|
|
XArray<WCHAR> aScope;
|
|
};
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CICommandCache
|
|
//
|
|
// Purpose: A cache for ICommands, since they are expensive to create
|
|
//
|
|
// History: 97/Feb/23 dlee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CICommandCache
|
|
{
|
|
public:
|
|
CICommandCache();
|
|
|
|
SCODE Make( ICommand ** ppCommand,
|
|
DWORD depth,
|
|
WCHAR const * pwcMachine,
|
|
WCHAR const * pwcCatalog,
|
|
WCHAR const * pwcScope );
|
|
|
|
void Release( ICommand * pCommand );
|
|
|
|
void Remove( ICommand * pCommand );
|
|
|
|
void Purge();
|
|
|
|
private:
|
|
SCODE ParseAndMake( ICommand ** ppCommand,
|
|
DWORD depth,
|
|
WCHAR const * pwcMachine,
|
|
WCHAR const * pwcCatalog,
|
|
WCHAR const * pwcScope );
|
|
|
|
ULONG _ulSig;
|
|
CMutexSem _mutex;
|
|
XArray<CICommandItem> _aItems;
|
|
XInterface<ISimpleCommandCreator> xCmdCreator;
|
|
};
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: CopyString
|
|
//
|
|
// Purpose: Simple method to allocate and copy a string (strdup)
|
|
//
|
|
// History: 99-Feb-10 dlee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
inline WCHAR * CopyString( WCHAR const *pwc )
|
|
{
|
|
unsigned c = wcslen( pwc ) + 1;
|
|
WCHAR *pwcNew = new WCHAR[c];
|
|
RtlCopyMemory( pwcNew, pwc, c * sizeof WCHAR );
|
|
return pwcNew;
|
|
} //CopyString
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CFormatItem
|
|
//
|
|
// Purpose: Formatting information for a given locale
|
|
//
|
|
// History: 99-Feb-10 dlee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CFormatItem
|
|
{
|
|
public:
|
|
CFormatItem( LCID lcid );
|
|
~CFormatItem();
|
|
|
|
void Copy( NUMBERFMT & numberFormat, CURRENCYFMT & currencyFormat ) const;
|
|
LCID GetLCID() const { return _lcid; }
|
|
|
|
private:
|
|
LCID _lcid;
|
|
NUMBERFMT _numberFormat;
|
|
CURRENCYFMT _currencyFormat;
|
|
};
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CFormattingCache
|
|
//
|
|
// Purpose: Cache of formatting information.
|
|
//
|
|
// History: 99-Feb-10 dlee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CFormattingCache
|
|
{
|
|
public:
|
|
CFormattingCache() {}
|
|
|
|
void GetFormattingInfo( LCID lcid,
|
|
NUMBERFMT & numberFormat,
|
|
CURRENCYFMT & currencyFormat );
|
|
void Purge();
|
|
|
|
private:
|
|
CMutexSem _mutex;
|
|
CCountedDynArray<CFormatItem> _aItems;
|
|
};
|
|
|
|
class CTheGlobalIDQVariables;
|
|
extern CTheGlobalIDQVariables * pTheGlobalIDQVariables;
|
|
|
|
class CIDQTheFirst
|
|
{
|
|
public:
|
|
CIDQTheFirst( CTheGlobalIDQVariables *p )
|
|
{
|
|
pTheGlobalIDQVariables = p;
|
|
}
|
|
};
|
|
|
|
class CTheGlobalIDQVariables
|
|
{
|
|
public:
|
|
CTheGlobalIDQVariables() :
|
|
#pragma warning(disable : 4355) // 'this' in a constructor
|
|
_first(this),
|
|
#pragma warning(default : 4355) // 'this' in a constructor
|
|
_fTheWebActiveXSearchShutdown(FALSE)
|
|
{
|
|
}
|
|
|
|
CIDQTheFirst _first;
|
|
BOOL _fTheWebActiveXSearchShutdown;
|
|
CIdqRegParams _TheIDQRegParams;
|
|
CICommandCache _TheICommandCache;
|
|
CWebResourceArbiter _TheWebResourceArbiter;
|
|
CWebPendingQueue _TheWebPendingRequestQueue;
|
|
CWQueryCache _TheWebQueryCache;
|
|
CFormattingCache _TheFormattingCache;
|
|
};
|
|
|
|
#define TheGlobalIDQVariables (*pTheGlobalIDQVariables)
|
|
|
|
#define TheIDQRegParams TheGlobalIDQVariables._TheIDQRegParams
|
|
#define TheWebQueryCache TheGlobalIDQVariables._TheWebQueryCache
|
|
#define TheWebPendingRequestQueue TheGlobalIDQVariables._TheWebPendingRequestQueue
|
|
#define TheWebResourceArbiter TheGlobalIDQVariables._TheWebResourceArbiter
|
|
#define fTheActiveXSearchShutdown TheGlobalIDQVariables._fTheWebActiveXSearchShutdown
|
|
#define TheICommandCache TheGlobalIDQVariables._TheICommandCache
|
|
#define TheFormattingCache TheGlobalIDQVariables._TheFormattingCache
|
|
|