/*++ Copyright (c) 1998 Microsoft Corporation Module Name: atqbmon.hxx Abstract: ATQ Backlog Monitor Author: 01-Dec-1998 MCourage Revision History: --*/ #ifndef __ATQBMON_HXX__ #define __ATQBMON_HXX__ #define ATQ_BMON_ENTRY_SIGNATURE ((DWORD) 'NOMB') // BMON #define ATQ_FREE_BMON_ENTRY_SIGNATURE ((DWORD) 'NOMX') // XMON #define ATQ_BMON_WAKEUP_MESSAGE ((DWORD) 'EKAW') // WAKE #define ATQ_BMON_WAKEUP_PORT (3456) #define ATQ_BMON_WAKEUP_PORT_MAX (3556) // // forwards // class ATQ_BACKLOG_MONITOR; class ATQ_BMON_ENTRY; class ATQ_BMON_WAKEUP_ENTRY; class ATQ_BMON_SET; // // globals // extern ATQ_BACKLOG_MONITOR * g_pAtqBacklogMonitor; // // Helper function // DWORD WINAPI BmonThreadFunc(LPVOID lpBmonSet); // // ATQ_BACKLOG_MONITOR // // This class is the main interface to the backlog monitor. // class ATQ_BACKLOG_MONITOR { public: ATQ_BACKLOG_MONITOR(); ~ATQ_BACKLOG_MONITOR(); BOOL AddEntry(ATQ_BMON_ENTRY * pBmonEntry); BOOL RemoveEntry(ATQ_BMON_ENTRY * pBmonEntry); BOOL PauseEntry(ATQ_BMON_ENTRY * pBmonEntry); BOOL ResumeEntry(ATQ_BMON_ENTRY * pBmonEntry); private: VOID Lock() { EnterCriticalSection( &m_csLock ); } VOID Unlock() { LeaveCriticalSection( &m_csLock ); } CRITICAL_SECTION m_csLock; LIST_ENTRY m_ListHead; }; // // enum BMON_ENTRY_OPCODE // // Tells the select thread what it should // do with a particular BMON_ENTRY // typedef enum _BMON_OPCODE { BMON_INVALID, BMON_WAIT, BMON_NOWAIT, BMON_PAUSE, BMON_RESUME, BMON_ADD, BMON_REMOVE } BMON_OPCODE; // // ATQ_BMON_ENTRY // // The client of the backlog monitor provides an instance // of this class which contains a socket descriptor and // a callback function which the client overrides. // class ATQ_BMON_ENTRY { public: ATQ_BMON_ENTRY(SOCKET s); virtual ~ATQ_BMON_ENTRY(); virtual BOOL Callback() = 0; // // these functions are used internally // by the monitor // BOOL InitEvent(); VOID SignalAddRemove(DWORD dwError); BOOL WaitForAddRemove(); VOID SetOpcode(BMON_OPCODE bmonOpcode) { m_BmonOpcode = bmonOpcode; } BMON_OPCODE GetOpcode() { return m_BmonOpcode; } VOID SetContainingBmonSet(ATQ_BMON_SET * pBmonSet) { m_pBmonSet = pBmonSet; } ATQ_BMON_SET * GetContainingBmonSet() { return m_pBmonSet; } DWORD GetError() { return m_dwErr; } SOCKET GetSocket() { return m_Socket; } BOOL CheckSignature() { return (m_Signature == ATQ_BMON_ENTRY_SIGNATURE); } private: DWORD m_Signature; SOCKET m_Socket; HANDLE m_hAddRemoveEvent; BMON_OPCODE m_BmonOpcode; ATQ_BMON_SET * m_pBmonSet; DWORD m_dwErr; }; // // BMON_WAKEUP_ENTRY // // This is a special entry whose purpose is to // wake up an ATQ_BMON_SET's thread so it can // call SynchronizeSets. // class BMON_WAKEUP_ENTRY : public ATQ_BMON_ENTRY { public: BMON_WAKEUP_ENTRY(SOCKET s, SOCKET s2) : ATQ_BMON_ENTRY(s), m_ExclusiveEnforce(s2) {} virtual ~BMON_WAKEUP_ENTRY() { if (m_ExclusiveEnforce != INVALID_SOCKET) { closesocket( m_ExclusiveEnforce); m_ExclusiveEnforce = INVALID_SOCKET; } } virtual BOOL Callback(); private: SOCKET m_ExclusiveEnforce; }; #define BMON_SELECT_ERROR 0x80000000 #define BMON_NOTIFY_ERROR 0x40000000 #define BMON_SENDTO_ERROR 0x20000000 // // ATQ_BMON_SET // // This class owns a set of listen sockets. It uses // select to see which listeners are out of AcceptEx // contexts. // class ATQ_BMON_SET { public: ATQ_BMON_SET(); ~ATQ_BMON_SET(); BOOL Initialize(); BOOL Cleanup(); BOOL IsEmpty(); BOOL IsNotFull(); BOOL AddEntry(ATQ_BMON_ENTRY * pBmonEntry); BOOL RemoveEntry(ATQ_BMON_ENTRY * pBmonEntry); BOOL PauseEntry(ATQ_BMON_ENTRY * pBmonEntry); BOOL ResumeEntry(ATQ_BMON_ENTRY * pBmonEntry); // // Called to tell thread to sleep after notifying // VOID DoSleep( BOOL fDoSleep ) { m_fDoSleep = fDoSleep; } // // Has the thread gone away? // BOOL ThreadFinished( VOID ) const { return m_fThreadFinished; } // // called (indirectly) by Initialize // VOID BmonThreadFunc(); LIST_ENTRY m_SetList; private: VOID Lock() { EnterCriticalSection( &m_csLock ); } VOID Unlock() { LeaveCriticalSection( &m_csLock ); } VOID Wakeup(); BOOL SynchronizeSets(); BOOL NotifyEntries(); CRITICAL_SECTION m_csLock; DWORD m_SetSize; ATQ_BMON_ENTRY * m_apEntrySet[FD_SETSIZE]; FD_SET m_ListenSet; BMON_WAKEUP_ENTRY * m_pWakeupEntry; WORD m_Port; BOOL m_fCleanup; HANDLE m_hThread; BOOL m_fDoSleep; BOOL m_fThreadFinished; DWORD m_dwError; }; #endif // __ATQBMON_HXX__