mirror of https://github.com/tongzx/nt5src
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.
626 lines
18 KiB
626 lines
18 KiB
/*-----------------------------------------------------------------------------
|
|
|
|
Copyright (c) 1995-1997 Microsoft Corporation
|
|
|
|
Module Name :
|
|
waminfo.hxx
|
|
|
|
Abstract:
|
|
Header file for WAMINFO object.
|
|
|
|
Author:
|
|
David Kaplan ( DaveK ) 11-Mar-1997
|
|
|
|
Environment:
|
|
User Mode - Win32
|
|
|
|
Project:
|
|
W3 services DLL
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
Forward references
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
#include <lkrhash.h>
|
|
#include <svmap.h>
|
|
#include <issched.hxx>
|
|
|
|
#ifndef __W3SVC_WAMINFO_HXX__
|
|
#define __W3SVC_WAMINFO_HXX__
|
|
#include "ptable.hxx"
|
|
|
|
interface IWam;
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
External definitions
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
typedef
|
|
LONG (WINAPI * PFN_INTERLOCKED_COMPARE_EXCHANGE)
|
|
(
|
|
LONG *Destination,
|
|
LONG Exchange,
|
|
LONG Comperand
|
|
);
|
|
|
|
extern PFN_INTERLOCKED_COMPARE_EXCHANGE g_pfnInterlockedCompareExchange;
|
|
|
|
HRESULT
|
|
CreateWamRequestInstance
|
|
(
|
|
HTTP_REQUEST * pHttpRequest,
|
|
EXEC_DESCRIPTOR * pExec,
|
|
const STR * pstrPath,
|
|
CWamInfo * pWamInfo,
|
|
WAM_REQUEST** ppWamRequestOut
|
|
);
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
WAM States Explaination
|
|
|
|
WIS_START This state is set in WamInfo constructor, and changed to WIS_RUNNING
|
|
if Init() succeeded. Therefore, a WamInfo in either hashtable or dyinglist
|
|
can not have this state.
|
|
|
|
WIS_RUNNING This state indicates the WAMINFO in the hashtable is ok to serving requests.
|
|
|
|
WIS_REPAIR This state indicates a thread is currently repair WAMINFO after it detects the outproc
|
|
Wam pointer is nolonger reachable via RPC(a crash). This state is only
|
|
applied to WamInfoOutProc.
|
|
|
|
WIS_PAUSE This state indicates the application is paused by metabase setting, therefore,
|
|
the WamInfo should be deleted such that next request will refresh the metabase
|
|
setting again.
|
|
|
|
WIS_CPUPAUSE This state indicates the application is paused by Job object control. An application
|
|
is in a zombie state that it does not have IWAM pointer(and other stuff) since the
|
|
out-proc mtx process is terminated.
|
|
|
|
WIS_SHUTDOWN This state indicates the WamInfo is in a shutdown stage. Therefore, any new requests
|
|
need to be rejected.
|
|
|
|
WIS_ERROR This state indicates the WamInfo is in some weired error state.(Currently, it is not
|
|
being used).
|
|
|
|
WIS_END This state indicates the WamInfo is in destructor mode.
|
|
|
|
|
|
General rules to change the state:
|
|
|
|
Use ChangeToState(oldstate, newstate), check whether the return value is same as oldstate.
|
|
-----------------------------------------------------------------------------*/
|
|
enum
|
|
{
|
|
WIS_START = 0,
|
|
WIS_RUNNING,
|
|
WIS_REPAIR,
|
|
WIS_PAUSE,
|
|
WIS_CPUPAUSE,
|
|
WIS_ERROR,
|
|
WIS_SHUTDOWN,
|
|
WIS_END,
|
|
WIS_MAX_STATE
|
|
};
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
class CWamInfo:
|
|
|
|
One-to-One relation with Wam object.
|
|
-----------------------------------------------------------------------------*/
|
|
class CWamInfo
|
|
{
|
|
public:
|
|
|
|
CWamInfo
|
|
(
|
|
const STR &strMetabasePath,
|
|
BOOL fInProcess,
|
|
BOOL fInPool,
|
|
BOOL fEnableTryExcept,
|
|
REFGUID clsidWam
|
|
);
|
|
|
|
virtual ~CWamInfo(void);
|
|
|
|
void Reference(void);
|
|
void Dereference(void);
|
|
void RecycleLock(void);
|
|
void RecycleUnlock(void);
|
|
// ------------------------------------------------------------
|
|
// WAM INFO's public functions
|
|
// ------------------------------------------------------------
|
|
|
|
HRESULT CreateWamInstance( DWORD dwContext );
|
|
|
|
|
|
virtual HRESULT Init
|
|
(
|
|
WCHAR* wszPackageId,
|
|
DWORD pidInetInfo
|
|
);
|
|
|
|
virtual HRESULT UnInit(void);
|
|
|
|
virtual void LeaveOOPZone(WAM_REQUEST * pWamRequest, BOOL fRecord);
|
|
|
|
virtual HRESULT GetStatistics
|
|
(
|
|
DWORD Level,
|
|
LPWAM_STATISTICS_INFO pWamStatsInfo
|
|
);
|
|
|
|
virtual void LoopWaitForActiveRequests
|
|
(
|
|
INT cIgnoreRefs
|
|
);
|
|
|
|
virtual HRESULT StartShutdown
|
|
(
|
|
INT cIgnoreRefs
|
|
); // NOTE StartShutdown is non-virtual so derived class can use it
|
|
|
|
virtual VOID NotifyGetInfoForName
|
|
(
|
|
IN LPCSTR pszServerVariable
|
|
);
|
|
|
|
virtual HRESULT DoProcessRequestCall
|
|
(
|
|
IN IWam * pIWam,
|
|
IN WAM_REQUEST * pWamRequest,
|
|
OUT BOOL * pfHandled
|
|
);
|
|
|
|
HRESULT ProcessAsyncIO
|
|
(
|
|
WAM_REQUEST* pWamRequest,
|
|
#ifdef _WIN64
|
|
UINT64 pWamExecInfoIn, // WamExecInfo *
|
|
#else
|
|
ULONG_PTR pWamExecInfoIn, // WamExecInfo *
|
|
#endif
|
|
DWORD dwStatus,
|
|
DWORD cbWritten,
|
|
LPBYTE lpOopReadData = NULL
|
|
);
|
|
|
|
|
|
HRESULT ProcessWamRequest
|
|
(
|
|
HTTP_REQUEST * pHttpRequest,
|
|
EXEC_DESCRIPTOR * pExec,
|
|
const STR * pstrPath,
|
|
BOOL * pfHandled,
|
|
BOOL * pfFinished
|
|
);
|
|
|
|
DWORD ChangeToState(DWORD dwState);
|
|
DWORD ChangeToState(DWORD dwOldState, DWORD dwNewState);
|
|
DWORD QueryState(void) const;
|
|
DWORD QueryCurrentRequests(void) const;
|
|
virtual VOID ClearMembers();
|
|
|
|
IWam* QueryIWam(void) const;
|
|
CProcessEntry* QueryProcessEntry(void) const;
|
|
DWORD PidWam(void) const;
|
|
DWORD FInProcess(void) const;
|
|
HANDLE HWamProcess(void) const;
|
|
const STR & QueryApplicationPath(void) const;
|
|
BOOL FCurrentStateValid(void) const;
|
|
|
|
LPCSTR CWamInfo::QueryKey() const;
|
|
void Print(void) const;
|
|
|
|
void Recycle
|
|
(
|
|
DWORD dwTimeInSec
|
|
);
|
|
|
|
DWORD QueryShutdownTimeLimit(void) const;
|
|
|
|
protected:
|
|
virtual HRESULT PreProcessWamRequest
|
|
(
|
|
IN WAM_REQUEST* pWamRequest,
|
|
IN HTTP_REQUEST* pHttpRequest,
|
|
OUT IWam** ppIWam,
|
|
OUT BOOL* pfHandled
|
|
);
|
|
|
|
virtual HRESULT PostProcessRequest
|
|
(
|
|
IN HRESULT hrIn,
|
|
IN WAM_REQUEST * pWamRequest
|
|
);
|
|
|
|
virtual HRESULT PreProcessAsyncIO
|
|
(
|
|
IN WAM_REQUEST * pWamRequest,
|
|
OUT IWam ** ppIWam
|
|
);
|
|
|
|
public:
|
|
LIST_ENTRY ListEntry; // Double link List node for linking to DyingList.
|
|
LIST_ENTRY leProcess; // Double Link List node for linking to the process entry.
|
|
BOOL m_fRecycled;
|
|
DWORD m_dwRecycleSchedulerCookie;
|
|
|
|
protected:
|
|
DWORD m_dwSignature;
|
|
|
|
IWam* m_pIWam;
|
|
|
|
DWORD m_dwIWamGipCookie; // GIP cookie to get thread-valid pIWams
|
|
CProcessEntry* m_pProcessEntry;
|
|
LONG m_cRef;
|
|
LONG m_cCurrentRequests;
|
|
LONG m_cTotalRequests;
|
|
DWORD m_dwState;
|
|
BOOL m_fInProcess;
|
|
BOOL m_fInPool;
|
|
BOOL m_fEnableTryExcept;
|
|
BOOL m_fShuttingDown;
|
|
STR m_strApplicationPath;
|
|
CLSID m_clsidWam;
|
|
LONG m_cMaxRequests;
|
|
DWORD m_dwShutdownTimeLimit;
|
|
DWORD m_dwRecycleTime;
|
|
|
|
static BOOL m_rgValidState[WIS_MAX_STATE];
|
|
|
|
CRITICAL_SECTION m_csRecycleLock;
|
|
};
|
|
|
|
inline void CWamInfo::Reference(void)
|
|
{
|
|
// DBGPRINTF((DBG_CONTEXT, "CWamInfo %p AddRef, m_cRef %d\n", this, m_cRef+1));
|
|
InterlockedIncrement(&m_cRef);
|
|
}
|
|
|
|
inline void CWamInfo::Dereference(void)
|
|
{
|
|
DBG_ASSERT(m_cRef > 0);
|
|
// DBGPRINTF((DBG_CONTEXT, "CWamInfo %p Release, m_cRef %d\n", this, m_cRef-1));
|
|
if ( 0 == InterlockedDecrement(&m_cRef) )
|
|
{
|
|
delete this;
|
|
}
|
|
}
|
|
|
|
inline DWORD CWamInfo::PidWam() const
|
|
{
|
|
return( m_pProcessEntry->QueryProcessId());
|
|
}
|
|
|
|
inline HANDLE CWamInfo::HWamProcess() const
|
|
{
|
|
return( m_pProcessEntry->QueryProcessHandle() );
|
|
}
|
|
|
|
inline DWORD CWamInfo::FInProcess() const
|
|
{
|
|
return( m_fInProcess );
|
|
}
|
|
|
|
inline BOOL CWamInfo::FCurrentStateValid(void) const
|
|
{
|
|
return (m_rgValidState[m_dwState]);
|
|
}
|
|
|
|
inline DWORD CWamInfo::QueryState(void) const
|
|
{
|
|
return (m_dwState);
|
|
}
|
|
|
|
inline DWORD CWamInfo::QueryCurrentRequests(void) const
|
|
{
|
|
return (m_cCurrentRequests);
|
|
}
|
|
|
|
inline CProcessEntry* CWamInfo::QueryProcessEntry(void) const
|
|
{
|
|
return m_pProcessEntry;
|
|
}
|
|
|
|
inline DWORD CWamInfo::ChangeToState(DWORD eState)
|
|
{
|
|
return (DWORD)InterlockedExchange((LONG *)&m_dwState, eState);
|
|
}
|
|
|
|
inline DWORD CWamInfo::ChangeToState(DWORD eOldState, DWORD eNewState)
|
|
{
|
|
return (DWORD)(*g_pfnInterlockedCompareExchange)((LONG *)&m_dwState, (LONG)eNewState, (LONG)eOldState);
|
|
}
|
|
|
|
inline IWam* CWamInfo::QueryIWam(void) const
|
|
{
|
|
return m_pIWam;
|
|
}
|
|
|
|
inline const STR &
|
|
CWamInfo::QueryApplicationPath(void) const
|
|
{
|
|
// returns the STR object containing the Application Root Path
|
|
return ( m_strApplicationPath);
|
|
}
|
|
|
|
inline void CWamInfo::LeaveOOPZone(WAM_REQUEST * pWamRequest, BOOL fRecord)
|
|
{
|
|
// No Op.
|
|
}
|
|
|
|
inline HRESULT CWamInfo::PostProcessRequest
|
|
(
|
|
IN HRESULT hrIn,
|
|
IN WAM_REQUEST * pWamRequest
|
|
)
|
|
{
|
|
return NOERROR;
|
|
}
|
|
|
|
inline DWORD CWamInfo::QueryShutdownTimeLimit(void) const
|
|
{
|
|
return m_dwShutdownTimeLimit;
|
|
}
|
|
|
|
inline VOID CWamInfo::RecycleLock(void)
|
|
{
|
|
Reference();
|
|
EnterCriticalSection( &m_csRecycleLock );
|
|
}
|
|
|
|
inline VOID CWamInfo::RecycleUnlock(void)
|
|
{
|
|
LeaveCriticalSection( &m_csRecycleLock );
|
|
Dereference();
|
|
}
|
|
|
|
class CWamInfoHash
|
|
: public CTypedHashTable<CWamInfoHash, CWamInfo, const char*>
|
|
{
|
|
public:
|
|
static const char* ExtractKey(const CWamInfo* pWamInfo);
|
|
|
|
static DWORD CalcKeyHash(const char* pszKey);
|
|
|
|
static bool EqualKeys(const char* pszKey1, const char* pszKey2);
|
|
|
|
static void AddRefRecord(CWamInfo* pWamInfo, int nIncr);
|
|
|
|
CWamInfoHash
|
|
(
|
|
double maxload, // Bound on average chain length,
|
|
size_t initsize, // Initial size of Hash Table
|
|
size_t num_subtbls // #subordinate hash tables.
|
|
)
|
|
: CTypedHashTable<CWamInfoHash, CWamInfo, const char*>
|
|
("WamInfo", maxload, initsize, num_subtbls)
|
|
{}
|
|
};
|
|
|
|
inline const char*
|
|
CWamInfoHash::ExtractKey(const CWamInfo* pWamInfo)
|
|
{
|
|
return pWamInfo->QueryKey();
|
|
}
|
|
|
|
inline DWORD
|
|
CWamInfoHash::CalcKeyHash(const char* pszKey)
|
|
{
|
|
return HashStringNoCase(pszKey);
|
|
}
|
|
|
|
inline bool
|
|
CWamInfoHash::EqualKeys(const char* pszKey1, const char* pszKey2)
|
|
{
|
|
return (_stricmp(pszKey1, pszKey2) == 0);
|
|
}
|
|
|
|
inline void
|
|
CWamInfoHash::AddRefRecord(CWamInfo* pWamInfo, int nIncr)
|
|
{
|
|
if (nIncr == 1)
|
|
{
|
|
pWamInfo->Reference();
|
|
}
|
|
else
|
|
{
|
|
pWamInfo->Dereference();
|
|
}
|
|
}
|
|
|
|
//======================== CWamInfoOutProc ====================================
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
// COOPWamReqList
|
|
//
|
|
// class that contains link list head for OOP Wam Requests of a WAM instance.
|
|
//
|
|
-----------------------------------------------------------------------------*/
|
|
class COOPWamReqList
|
|
{
|
|
public:
|
|
COOPWamReqList(void);
|
|
~COOPWamReqList(void);
|
|
|
|
BOOL FTimeToCleanup(DWORD dwCurrentTime);
|
|
BOOL FActive(void);
|
|
void SetTimeStamp(void);
|
|
|
|
LIST_ENTRY m_leRecoverListLink; // Link with other COOPWamReqList.
|
|
LIST_ENTRY m_leOOPWamReqListHead; // Cleanup List Head
|
|
private:
|
|
DWORD m_dwTimeStamp; // TimeStamp for Cleanup Scheduler
|
|
// (GetTickerCount)
|
|
BOOL m_fActive; // FALSE if the corresponding Wam
|
|
// crashed.
|
|
};
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
// COOPWamReqList::SetTimeStamp
|
|
//
|
|
// Set time stamp when Out Proc Wam crashes.
|
|
-----------------------------------------------------------------------------*/
|
|
inline void
|
|
COOPWamReqList::SetTimeStamp(void)
|
|
{
|
|
m_dwTimeStamp = GetTickCount();
|
|
m_fActive = FALSE;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
//COOPWamReqList::FActive
|
|
//
|
|
//Return whether the list is Active or not(m_fActive).
|
|
-----------------------------------------------------------------------------*/
|
|
inline BOOL
|
|
COOPWamReqList::FActive(void)
|
|
{
|
|
return m_fActive;
|
|
}
|
|
|
|
class CWamInfoOutProc : public CWamInfo
|
|
{
|
|
public:
|
|
PLIST_ENTRY m_pCurrentListHead; // pointer to an OOPWamReq ListHead
|
|
// with current valid OOP WAM.
|
|
private:
|
|
DWORD m_fInRepair; // flag indicates WamInfo in crash-recovery mode or not.
|
|
DWORD m_fNoMoreRecovery; // flag indicates WamInfo failed to ReInitWam() or not.
|
|
|
|
HANDLE m_hPermitOOPEvent; // Event that serve as a gate to OutofProc processing
|
|
// Signaled when normal processing
|
|
// Reset during the crash-recovery
|
|
CRITICAL_SECTION m_csList; // Critical section for RecoverList.
|
|
|
|
LIST_ENTRY m_rgRecoverListHead;// pointer to an Array of cleanup list
|
|
DWORD m_dwThreshold; // Threshold for number of active cleanup list.
|
|
DWORD m_dwWamVersion; // Current valid WAM verion number.
|
|
DWORD m_cRecoverList; // # of active cleanup list in the system(started with 1)
|
|
DWORD m_idScheduled; // Scheduler ID for Schedule a work item.
|
|
BOOL m_fJobEnabled;
|
|
PW3_SERVER_INSTANCE m_pwsiInstance;
|
|
|
|
SV_CACHE_LIST m_svCache;
|
|
|
|
public:
|
|
CWamInfoOutProc
|
|
(
|
|
const STR & strMetabasePath,
|
|
BOOL fInProcess,
|
|
BOOL fInPool,
|
|
BOOL fEnableTryExcept,
|
|
REFGUID clsidWam,
|
|
DWORD dwThreshold,
|
|
PW3_SERVER_INSTANCE pwiInstance,
|
|
BOOL fJobEnabled,
|
|
DWORD dwPeriodicRestartRequests,
|
|
DWORD dwPeriodicRestartTime,
|
|
DWORD dwShutdownTimeLimit
|
|
);
|
|
|
|
virtual ~CWamInfoOutProc();
|
|
|
|
HRESULT GetStatistics
|
|
(
|
|
DWORD Level,
|
|
LPWAM_STATISTICS_INFO pWamStatsInfo
|
|
);
|
|
|
|
static void WINAPI CleanupScheduled(void *pContext);
|
|
|
|
|
|
VOID ClearMembers();
|
|
|
|
private:
|
|
HRESULT PreProcessWamRequest
|
|
(
|
|
IN WAM_REQUEST* pWamRequest,
|
|
IN HTTP_REQUEST* pHttpRequest,
|
|
OUT IWam** ppIWam,
|
|
OUT BOOL* pfHandled
|
|
);
|
|
|
|
HRESULT PostProcessRequest
|
|
(
|
|
IN HRESULT hrIn,
|
|
IN WAM_REQUEST * pWamRequest
|
|
);
|
|
|
|
HRESULT PreProcessAsyncIO
|
|
(
|
|
IN WAM_REQUEST * pWamRequest,
|
|
OUT IWam ** ppIWam
|
|
);
|
|
|
|
HRESULT Init
|
|
(
|
|
IN WCHAR* wszPackageId,
|
|
IN DWORD pidInetInfo
|
|
);
|
|
|
|
HRESULT UnInit(void);
|
|
|
|
VOID NotifyGetInfoForName
|
|
(
|
|
IN LPCSTR pszServerVariable
|
|
);
|
|
|
|
HRESULT DoProcessRequestCall
|
|
(
|
|
IN IWam * pIWam,
|
|
IN WAM_REQUEST * pWamRequest,
|
|
OUT BOOL * pfHandled
|
|
);
|
|
|
|
IWam * EnterOOPZone(WAM_REQUEST * pWamRequest, DWORD *pdwWamVersion, BOOL fRecord);
|
|
void LeaveOOPZone(WAM_REQUEST * pWamRequest, BOOL fRecord);
|
|
|
|
void LoopWaitForActiveRequests(INT cIgnoreRefs);
|
|
|
|
BOOL FExceedCrashLimit(void);
|
|
HRESULT Repair(void);
|
|
HRESULT ReInitWam(void);
|
|
BOOL FinalCleanup(void);
|
|
BOOL CleanupAll(BOOL fScheduled);
|
|
BOOL Cleanup(COOPWamReqList *pCleanupList);
|
|
|
|
void LockList(void);
|
|
void UnLockList(void);
|
|
|
|
public:
|
|
DWORD GetWamVersion(void);
|
|
BOOL IsJobEnabled() {return m_fJobEnabled;};
|
|
};
|
|
|
|
inline BOOL
|
|
CWamInfoOutProc::FExceedCrashLimit(void)
|
|
{
|
|
return (m_dwWamVersion >= m_dwThreshold || m_fNoMoreRecovery);
|
|
}
|
|
|
|
inline DWORD
|
|
CWamInfoOutProc::GetWamVersion(void)
|
|
{
|
|
return ( m_dwWamVersion );
|
|
}
|
|
|
|
inline void
|
|
CWamInfoOutProc::LockList(void)
|
|
{
|
|
EnterCriticalSection(&m_csList);
|
|
}
|
|
|
|
inline void
|
|
CWamInfoOutProc::UnLockList(void)
|
|
{
|
|
LeaveCriticalSection(&m_csList);
|
|
}
|
|
|
|
#endif __W3SVC_WAMINFO_HXX__
|
|
|