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.
383 lines
7.1 KiB
383 lines
7.1 KiB
//***************************************************************************
|
|
|
|
//
|
|
|
|
// PROVTHRD.H
|
|
|
|
//
|
|
|
|
// Module: OLE MS PROVIDER FRAMEWORK
|
|
|
|
//
|
|
|
|
// Copyright (c) 1996-2001 Microsoft Corporation, All Rights Reserved
|
|
//
|
|
//***************************************************************************
|
|
|
|
#ifndef __PROVTHREAD_PROVTHRD_H__
|
|
#define __PROVTHREAD_PROVTHRD_H__
|
|
|
|
#include <Allocator.h>
|
|
#include <Queue.h>
|
|
#include <BasicTree.h>
|
|
|
|
extern WmiAllocator g_Allocator ;
|
|
|
|
class ProvThreadObject ;
|
|
class ProvAbstractTaskObject ;
|
|
class ProvTaskObject ;
|
|
|
|
typedef WmiBasicTree <HANDLE,ProvEventObject *> ScheduleReapContainer ;
|
|
typedef WmiBasicTree <HANDLE,ProvEventObject *> :: Iterator ScheduleReapContainerIterator ;
|
|
|
|
typedef WmiBasicTree <DWORD,ProvThreadObject *> ThreadContainer ;
|
|
typedef WmiBasicTree <DWORD,ProvThreadObject *> :: Iterator ThreadContainerIterator ;
|
|
|
|
typedef WmiQueue <ProvAbstractTaskObject *,8> TaskQueue ;
|
|
|
|
class ProvThreadObject : private ProvEventObject
|
|
{
|
|
friend ProvAbstractTaskObject ;
|
|
friend BOOL APIENTRY DllMain (
|
|
|
|
HINSTANCE hInstance,
|
|
ULONG ulReason ,
|
|
LPVOID pvReserved
|
|
) ;
|
|
|
|
public:
|
|
|
|
static LONG s_ReferenceCount ;
|
|
|
|
private:
|
|
|
|
// Mutual exclusion mechanism
|
|
|
|
static CStaticCriticalSection s_Lock ;
|
|
|
|
ScheduleReapContainer m_ScheduleReapContainer ;
|
|
|
|
// Thread Name
|
|
|
|
TCHAR *m_ThreadName ;
|
|
|
|
// Terminate thread event
|
|
|
|
ProvEventObject m_ThreadTerminateEvent ;
|
|
|
|
// TaskObject created if a PostSignalThreadShutdown is called
|
|
|
|
ProvAbstractTaskObject *m_pShutdownTask ;
|
|
|
|
// Thread Initialization Event
|
|
|
|
HANDLE m_ThreadInitialization ;
|
|
|
|
// thread information
|
|
|
|
ULONG m_ThreadId ;
|
|
HANDLE m_ThreadHandle ;
|
|
DWORD m_timeout;
|
|
|
|
// list of task objects associated with thread object
|
|
|
|
TaskQueue m_TaskQueue ;
|
|
|
|
// Evict thread from process
|
|
|
|
void TerminateThread () ;
|
|
|
|
// Attach thread to global list of threads
|
|
|
|
BOOL RegisterThread () ;
|
|
|
|
// Remove thread from global list of threads
|
|
|
|
BOOL RemoveThread () ;
|
|
|
|
private:
|
|
|
|
// global list of thread objects keyed on thread identifier
|
|
|
|
static ThreadContainer s_ThreadContainer ;
|
|
|
|
HANDLE *m_EventContainer ;
|
|
ULONG m_EventContainerLength ;
|
|
|
|
HANDLE *GetEventHandles () ;
|
|
ULONG GetEventHandlesSize () ;
|
|
|
|
void ConstructEventContainer () ;
|
|
|
|
void Process () ;
|
|
BOOL Wait () ;
|
|
|
|
ProvAbstractTaskObject *GetTaskObject ( HANDLE &eventHandle ) ;
|
|
|
|
BOOL WaitDispatch ( ULONG t_HandleIndex , BOOL &a_Terminated ) ;
|
|
|
|
private:
|
|
|
|
// Thread entry point
|
|
|
|
static void _cdecl ThreadExecutionProcedure ( void *threadParameter ) ;
|
|
|
|
// Attach Process
|
|
|
|
static void ProcessAttach () ;
|
|
|
|
// Detach Process
|
|
|
|
static void ProcessDetach ( BOOL a_ProcessDetaching = FALSE ) ;
|
|
|
|
HANDLE *GetThreadHandleReference () { return &m_ThreadHandle ; }
|
|
|
|
protected:
|
|
public:
|
|
|
|
ProvThreadObject ( const TCHAR *a_ThreadName = NULL, DWORD a_timeout = INFINITE ) ;
|
|
|
|
void BeginThread();
|
|
|
|
virtual ~ProvThreadObject () ;
|
|
|
|
BOOL WaitForStartup () ;
|
|
|
|
void SignalThreadShutdown () ;
|
|
void PostSignalThreadShutdown () ;
|
|
|
|
// Get thread information
|
|
|
|
ULONG GetThreadId () { return m_ThreadId ; }
|
|
HANDLE GetThreadHandle () { return m_ThreadHandle ; }
|
|
|
|
BOOL ScheduleTask ( ProvAbstractTaskObject &a_TaskObject ) ;
|
|
BOOL ReapTask ( ProvAbstractTaskObject &a_TaskObject ) ;
|
|
|
|
virtual void Initialise () {} ;
|
|
virtual void Uninitialise () {} ;
|
|
virtual void TimedOut() {} ;
|
|
|
|
// Get Thread object associated with current thread
|
|
|
|
static ProvThreadObject *GetThreadObject () ;
|
|
|
|
static BOOL Startup () ;
|
|
static void Closedown() ;
|
|
|
|
} ;
|
|
|
|
class ProvAbstractTaskObject
|
|
{
|
|
friend ProvThreadObject ;
|
|
private:
|
|
|
|
// list of thread objects keyed on thread identifier
|
|
|
|
ThreadContainer m_ThreadContainer ;
|
|
|
|
CCriticalSection m_Lock ;
|
|
|
|
ProvEventObject m_CompletionEvent ;
|
|
ProvEventObject m_AcknowledgementEvent ;
|
|
HANDLE m_ScheduledHandle;
|
|
DWORD m_timeout;
|
|
|
|
BOOL WaitDispatch ( ProvThreadObject *a_ThreadObject , HANDLE a_Handle , BOOL &a_Processed ) ;
|
|
BOOL WaitAcknowledgementDispatch ( ProvThreadObject *a_ThreadObject , HANDLE a_Handle , BOOL &a_Processed ) ;
|
|
|
|
void AttachTaskToThread ( ProvThreadObject &a_ThreadObject ) ;
|
|
void DetachTaskFromThread ( ProvThreadObject &a_ThreadObject ) ;
|
|
|
|
protected:
|
|
|
|
ProvAbstractTaskObject (
|
|
|
|
const TCHAR *a_GlobalTaskNameComplete = NULL,
|
|
const TCHAR *a_GlobalTaskNameAcknowledgement = NULL,
|
|
DWORD a_timeout = INFINITE
|
|
|
|
) ;
|
|
|
|
virtual HANDLE GetHandle() = 0;
|
|
|
|
public:
|
|
|
|
virtual ~ProvAbstractTaskObject () ;
|
|
|
|
virtual void Process () { Complete () ; }
|
|
virtual void Exec () {} ;
|
|
virtual void Complete () { m_CompletionEvent.Set () ; }
|
|
virtual BOOL Wait ( BOOL a_Dispatch = FALSE ) ;
|
|
virtual void Acknowledge () { m_AcknowledgementEvent.Set () ; }
|
|
virtual BOOL WaitAcknowledgement ( BOOL a_Dispatch = FALSE ) ;
|
|
virtual void TimedOut() {} ;
|
|
} ;
|
|
|
|
|
|
class ProvTaskObject : public ProvAbstractTaskObject
|
|
{
|
|
private:
|
|
ProvEventObject m_Event;
|
|
protected:
|
|
public:
|
|
|
|
ProvTaskObject (
|
|
|
|
const TCHAR *a_GlobalTaskNameStart = NULL ,
|
|
const TCHAR *a_GlobalTaskNameComplete = NULL,
|
|
const TCHAR *a_GlobalTaskNameAcknowledgement = NULL,
|
|
DWORD a_timeout = INFINITE
|
|
|
|
) ;
|
|
|
|
~ProvTaskObject () {} ;
|
|
void Exec () { m_Event.Set(); }
|
|
HANDLE GetHandle () { return m_Event.GetHandle() ; }
|
|
} ;
|
|
|
|
template <typename FT, FT F, BOOL Condition_> class VoidOnDeleteIf
|
|
{
|
|
private:
|
|
BOOL Condition_;
|
|
BOOL bExec;
|
|
|
|
public:
|
|
VoidOnDeleteIf ( ): bExec ( FALSE )
|
|
{
|
|
};
|
|
|
|
void Exec ( )
|
|
{
|
|
if ( Condition_ )
|
|
{
|
|
F ( );
|
|
bExec = TRUE;
|
|
}
|
|
}
|
|
|
|
~VoidOnDeleteIf ( )
|
|
{
|
|
if ( !bExec )
|
|
{
|
|
Exec ();
|
|
}
|
|
};
|
|
};
|
|
|
|
template <typename FT, FT F, BOOL const &Condition_> class VoidOnDeleteIfNot
|
|
{
|
|
private:
|
|
BOOL bExec;
|
|
|
|
public:
|
|
VoidOnDeleteIfNot ( ): bExec ( FALSE )
|
|
{
|
|
};
|
|
|
|
void Exec ( )
|
|
{
|
|
if ( !Condition_ )
|
|
{
|
|
F ( );
|
|
bExec = TRUE;
|
|
}
|
|
}
|
|
|
|
~VoidOnDeleteIfNot ( )
|
|
{
|
|
if ( !bExec )
|
|
{
|
|
Exec ();
|
|
}
|
|
};
|
|
};
|
|
|
|
template <typename T, typename FT, FT F> class ProvOnDelete
|
|
{
|
|
private:
|
|
T Val_;
|
|
BOOL bExec;
|
|
|
|
public:
|
|
ProvOnDelete ( T Val ): Val_ ( Val ), bExec ( FALSE )
|
|
{
|
|
};
|
|
|
|
void Exec ( )
|
|
{
|
|
F(Val_);
|
|
bExec = TRUE;
|
|
}
|
|
|
|
~ProvOnDelete ( )
|
|
{
|
|
if ( !bExec )
|
|
{
|
|
Exec ();
|
|
}
|
|
};
|
|
};
|
|
|
|
template<class T> class CProvFreeMe
|
|
{
|
|
protected:
|
|
T* m_p;
|
|
|
|
public:
|
|
CProvFreeMe(T* p) : m_p(p){}
|
|
~CProvFreeMe() {free ( m_p );}
|
|
};
|
|
|
|
template<class T> class CProvDeleteMe
|
|
{
|
|
protected:
|
|
T* m_p;
|
|
|
|
public:
|
|
CProvDeleteMe(T* p) : m_p(p){}
|
|
~CProvDeleteMe() {delete m_p;}
|
|
};
|
|
|
|
template<class T> class CProvDeleteMeArray
|
|
{
|
|
protected:
|
|
T* m_p;
|
|
|
|
public:
|
|
CProvDeleteMeArray(T* p) : m_p(p){}
|
|
~CProvDeleteMeArray() {delete [] m_p;}
|
|
};
|
|
|
|
#ifndef __WAITEX__
|
|
#define __WAITEX__
|
|
|
|
template < typename T, typename FT, FT F, int iTime >
|
|
class WaitException
|
|
{
|
|
public:
|
|
WaitException ( T Val_ )
|
|
{
|
|
BOOL bResult = FALSE;
|
|
while ( ! bResult )
|
|
{
|
|
try
|
|
{
|
|
F ( Val_ );
|
|
bResult = TRUE;
|
|
}
|
|
catch ( ... )
|
|
{
|
|
}
|
|
|
|
if ( ! bResult )
|
|
{
|
|
::Sleep ( iTime );
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif __WAITEX__
|
|
|
|
#endif //__PROVTHREAD_PROVTHRD_H__
|