Leaked source code of windows server 2003
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

//***************************************************************************
//
// 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