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.
282 lines
7.9 KiB
282 lines
7.9 KiB
//***************************************************************************
|
|
|
|
//
|
|
|
|
// 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 KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
class EventMap : public CObject
|
|
{
|
|
private:
|
|
|
|
CMap <KEY, ARG_KEY, VALUE, ARG_VALUE> 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<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
EventMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: EventMap ()
|
|
{
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
EventMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: ~EventMap ()
|
|
{
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
int EventMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: GetCount() const
|
|
{
|
|
int count = m_cmap.GetCount () ;
|
|
return count ;
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
BOOL EventMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: IsEmpty() const
|
|
{
|
|
return m_cmap.IsEmpty () ;
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
BOOL EventMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: Lookup(ARG_KEY key, VALUE& rValue) const
|
|
{
|
|
return m_cmap.Lookup ( key , rValue ) ;
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
VALUE& EventMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: operator[](ARG_KEY key)
|
|
{
|
|
return m_cmap.operator [] ( key ) ;
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
void EventMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: SetAt(ARG_KEY key, ARG_VALUE newValue)
|
|
{
|
|
m_cmap.SetAt ( key , newValue ) ;
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
BOOL EventMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: RemoveKey(ARG_KEY key)
|
|
{
|
|
return m_cmap.RemoveKey ( key ) ;
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
void EventMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: RemoveAll()
|
|
{
|
|
m_cmap.RemoveAll () ;
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
POSITION EventMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: GetStartPosition() const
|
|
{
|
|
return m_cmap.GetStartPosition () ;
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
void EventMap <KEY, ARG_KEY, VALUE, ARG_VALUE>:: 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 KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
class ThreadMap : public CObject
|
|
{
|
|
private:
|
|
CCriticalSection * criticalSection ;
|
|
CMap <KEY, ARG_KEY, VALUE, ARG_VALUE> 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<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
ThreadMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: ThreadMap () :
|
|
criticalSection(NULL)
|
|
{
|
|
criticalSection = new CCriticalSection ;
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
ThreadMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: ~ThreadMap ()
|
|
{
|
|
//this may be null
|
|
delete criticalSection ;
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
int ThreadMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: GetCount() const
|
|
{
|
|
criticalSection->Lock () ;
|
|
int count = cmap.GetCount () ;
|
|
criticalSection->Unlock () ;
|
|
return count ;
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
BOOL ThreadMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: IsEmpty() const
|
|
{
|
|
if (TRUE == m_bMakeThreadSafe)
|
|
{
|
|
criticalSection->Lock () ;
|
|
BOOL isEmpty = cmap.IsEmpty () ;
|
|
criticalSection->Unlock () ;
|
|
return isEmpty ;
|
|
}
|
|
else
|
|
{
|
|
return cmap.IsEmpty () ;
|
|
}
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
BOOL ThreadMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: Lookup(ARG_KEY key, VALUE& rValue) const
|
|
{
|
|
criticalSection->Lock () ;
|
|
BOOL lookup = cmap.Lookup ( key , rValue ) ;
|
|
criticalSection->Unlock () ;
|
|
return lookup ;
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
VALUE& ThreadMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: operator[](ARG_KEY key)
|
|
{
|
|
criticalSection->Lock () ;
|
|
VALUE &value = cmap.operator [] ( key ) ;
|
|
criticalSection->Unlock () ;
|
|
return value ;
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
void ThreadMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: SetAt(ARG_KEY key, ARG_VALUE newValue)
|
|
{
|
|
criticalSection->Lock () ;
|
|
cmap.SetAt ( key , newValue ) ;
|
|
criticalSection->Unlock () ;
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
BOOL ThreadMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: RemoveKey(ARG_KEY key)
|
|
{
|
|
criticalSection->Lock () ;
|
|
BOOL removeKey = cmap.RemoveKey ( key ) ;
|
|
criticalSection->Unlock () ;
|
|
return removeKey ;
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
void ThreadMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: RemoveAll()
|
|
{
|
|
criticalSection->Lock () ;
|
|
cmap.RemoveAll () ;
|
|
criticalSection->Unlock () ;
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
POSITION ThreadMap <KEY, ARG_KEY, VALUE, ARG_VALUE> :: GetStartPosition() const
|
|
{
|
|
criticalSection->Lock () ;
|
|
POSITION position = cmap.GetStartPosition () ;
|
|
criticalSection->Unlock () ;
|
|
return position ;
|
|
}
|
|
|
|
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
|
|
void ThreadMap <KEY, ARG_KEY, VALUE, ARG_VALUE>:: 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 <HANDLE, HANDLE, HANDLE,HANDLE> m_UserEvents ;
|
|
static ThreadMap <CThread*, CThread*, CThread*,CThread*> 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
|