//*************************************************************************** // // File: // // Module: MS SNMP Provider // // Purpose: // // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved // //*************************************************************************** #ifndef _THREAD_H_ #define _THREAD_H_ #define THREAD_STARED 100 #define WAIT_EVENT_0 WAIT_OBJECT_0 #define WAIT_EVENT_FAILED (MAXIMUM_WAIT_OBJECTS+1) #define WAIT_EVENT_ABANDONED (MAXIMUM_WAIT_OBJECTS+2) #define WAIT_EVENT_TERMINATED (MAXIMUM_WAIT_OBJECTS+3) typedef void (*PVOIDTHREADPROC)(void *); /* * Each connection is saved so that we can enumerate, delete, and trigger * This template provides the container for the connections and cookies */ template class EventMap : public CObject { private: CMap m_cmap ; protected: public: EventMap () ; virtual ~EventMap () ; int GetCount () const ; BOOL IsEmpty () const ; BOOL Lookup(ARG_KEY key, VALUE& rValue) const ; VALUE& operator[](ARG_KEY key) ; void SetAt(ARG_KEY key, ARG_VALUE newValue) ; BOOL RemoveKey(ARG_KEY key) ; void RemoveAll () ; POSITION GetStartPosition() const ; void GetNextAssoc(POSITION& rNextPosition, KEY& rKey, VALUE& rValue) const ; } ; template EventMap :: EventMap () { } template EventMap :: ~EventMap () { } template int EventMap :: GetCount() const { int count = m_cmap.GetCount () ; return count ; } template BOOL EventMap :: IsEmpty() const { return m_cmap.IsEmpty () ; } template BOOL EventMap :: Lookup(ARG_KEY key, VALUE& rValue) const { return m_cmap.Lookup ( key , rValue ) ; } template VALUE& EventMap :: operator[](ARG_KEY key) { return m_cmap.operator [] ( key ) ; } template void EventMap :: SetAt(ARG_KEY key, ARG_VALUE newValue) { m_cmap.SetAt ( key , newValue ) ; } template BOOL EventMap :: RemoveKey(ARG_KEY key) { return m_cmap.RemoveKey ( key ) ; } template void EventMap :: RemoveAll() { m_cmap.RemoveAll () ; } template POSITION EventMap :: GetStartPosition() const { return m_cmap.GetStartPosition () ; } template void EventMap :: GetNextAssoc(POSITION& rNextPosition, KEY& rKey, VALUE& rValue) const { m_cmap.GetNextAssoc ( rNextPosition , rKey , rValue ) ; } /*InterfaceGarbageCollector makes it easier to use the interface *by remembering to release them when you fall out of scope. The is *useful when you are using an IMosProvider and have lots of points *of failure; you can just give up and let the wrapper clean up for *you. */ template class ThreadMap : public CObject { private: CCriticalSection * criticalSection ; CMap cmap ; protected: public: ThreadMap (); virtual ~ThreadMap () ; int GetCount () const ; BOOL IsEmpty () const ; BOOL Lookup(ARG_KEY key, VALUE& rValue) const ; VALUE& operator[](ARG_KEY key) ; void SetAt(ARG_KEY key, ARG_VALUE newValue) ; BOOL RemoveKey(ARG_KEY key) ; void RemoveAll () ; POSITION GetStartPosition() const ; void GetNextAssoc(POSITION& rNextPosition, KEY& rKey, VALUE& rValue) const ; } ; template ThreadMap :: ThreadMap () : criticalSection(NULL) { criticalSection = new CCriticalSection ; } template ThreadMap :: ~ThreadMap () { //this may be null delete criticalSection ; } template int ThreadMap :: GetCount() const { criticalSection->Lock () ; int count = cmap.GetCount () ; criticalSection->Unlock () ; return count ; } template BOOL ThreadMap :: IsEmpty() const { if (TRUE == m_bMakeThreadSafe) { criticalSection->Lock () ; BOOL isEmpty = cmap.IsEmpty () ; criticalSection->Unlock () ; return isEmpty ; } else { return cmap.IsEmpty () ; } } template BOOL ThreadMap :: Lookup(ARG_KEY key, VALUE& rValue) const { criticalSection->Lock () ; BOOL lookup = cmap.Lookup ( key , rValue ) ; criticalSection->Unlock () ; return lookup ; } template VALUE& ThreadMap :: operator[](ARG_KEY key) { criticalSection->Lock () ; VALUE &value = cmap.operator [] ( key ) ; criticalSection->Unlock () ; return value ; } template void ThreadMap :: SetAt(ARG_KEY key, ARG_VALUE newValue) { criticalSection->Lock () ; cmap.SetAt ( key , newValue ) ; criticalSection->Unlock () ; } template BOOL ThreadMap :: RemoveKey(ARG_KEY key) { criticalSection->Lock () ; BOOL removeKey = cmap.RemoveKey ( key ) ; criticalSection->Unlock () ; return removeKey ; } template void ThreadMap :: RemoveAll() { criticalSection->Lock () ; cmap.RemoveAll () ; criticalSection->Unlock () ; } template POSITION ThreadMap :: GetStartPosition() const { criticalSection->Lock () ; POSITION position = cmap.GetStartPosition () ; criticalSection->Unlock () ; return position ; } template void ThreadMap :: GetNextAssoc(POSITION& rNextPosition, KEY& rKey, VALUE& rValue) const { criticalSection->Lock () ; cmap.GetNextAssoc ( rNextPosition , rKey , rValue ) ; criticalSection->Unlock () ; } class CThread { private: BOOL bWaiting; HANDLE m_hThreadStopEvent; HANDLE m_hThreadSyncEvent; DWORD m_cRef; EventMap m_UserEvents ; static ThreadMap m_ThreadMap ; protected: uintptr_t m_ulThreadHandle; public: CThread(); virtual ~CThread(); SCODE Start(); SCODE Stop(); SCODE Wait(DWORD timeout = INFINITE); virtual SCODE Process(){return S_OK;}; void AddEvent(HANDLE userEvent){m_UserEvents.SetAt(userEvent,userEvent);} void DeleteEvent(HANDLE userEvent){m_UserEvents.RemoveKey(userEvent);} void Exit(){SetEvent(m_hThreadSyncEvent);} ULONG AddRef(void){return ++m_cRef;} ULONG Release(void); operator void*(); static void ProcessDetach(); }; #endif