Source code of Windows XP (NT5)
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.
|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995
//
// File: thrdcomm.h
//
// Contents: Contains the inter-thread communication class
//
//----------------------------------------------------------------------------
//****************************************************************************
//
// Forward declarations
//
//****************************************************************************
class CThreadComm;
//****************************************************************************
//
// Classes
//
//****************************************************************************
//+---------------------------------------------------------------------------
//
// Class: CThreadComm (ctc)
//
// Purpose: Base class which handles cross-thread communication. This
// is the only class with methods that can safely be called
// by any thread. All other classes must have their methods
// called by their owning thread (except the ctor/dtor and Init
// which are called by the creating thread).
//
//----------------------------------------------------------------------------
class CThreadComm : public IUnknown, public CThreadLock { public: DECLARE_MEMCLEAR_NEW_DELETE();
// Thread-unsafe member functions - can only be called by owning (or
// creating) thread.
CThreadComm(); ~CThreadComm();
HRESULT StartThread(void * pvParams); BOOL Shutdown(CThreadComm * pTarget);
static DWORD TempThreadRoutine(LPVOID pvParam); virtual DWORD ThreadMain() = 0; // Used to tell StartThread that the new thread is going and has picked
// up all of its parameters.
// If fSuccess is false, then the thread will be terminating
// immediatly, and StartThread() will wait for it to do so.
void ThreadStarted(HRESULT hrThread) { _hrThread = hrThread; SetEvent(_hThreadReady); // Signal the other thread
::Sleep(100); // Yield to the other thread
}
BOOL GetNextMsg(THREADMSG *tm, void * pData, DWORD *cbData); void Reply(DWORD dwReply);
void SetName(LPCSTR szName);
// -----------------------------------------------------------------
//
// Thread-safe member functions - can be called by any thread.
HANDLE hThread() { return _hThread; }
void PostToThread(CThreadComm *pTarget, THREADMSG tm, void * pData = NULL, DWORD cbData = 0); DWORD SendToThread(CThreadComm *pTarget, THREADMSG tm, void * pData = NULL, DWORD cbData = 0);
// End of thread-safe member list
//
// -----------------------------------------------------------------
protected: virtual BOOL Init();
//
// Every method on objects that derive from CThreadComm should have
// VERIFY_THREAD at the beginning. VERIFY_THREAD ensures that the proper
// thread is calling the method (i.e. it ensure that proper apartment rules
// are being followed.)
//
inline void VERIFY_THREAD() { Assert(GetCurrentThreadId() == _dwThreadId); }
HANDLE _hThreadReady; // Event signaled when the new thread has set its return value
HANDLE _hCommEvent; // Event signaled when there is a message
DWORD _dwThreadId; HANDLE _hThread; void * _pvParams; HRESULT _hrThread; // The new thread sets this for initial success/failure.
private:
//
// MSGDATABUFSIZE: Max size of a thread message. The -40 is to keep the
// MESSAGEDATA struct below 1K.
//
#define MSGDATABUFSIZE (1024 - 40)
//
// MESSAGEDATA: All the data associated with a thread message.
//
struct MESSAGEDATA { MESSAGEDATA *pNext; THREADMSG tmMessage; DWORD dwResult; HANDLE hResultEvt; DWORD cbData; BYTE bData[MSGDATABUFSIZE]; };
#if DBG == 1
typedef struct tagTHREADNAME_INFO { DWORD dwType; // == 0x1000
LPCSTR szName; DWORD dwThreadID; DWORD dwFlags; } THREADNAME_INFO; #endif
DWORD SendHelper(THREADMSG tm, void * pData, DWORD cbData, BOOL fSend, HANDLE hResultEvt);
// ***************************
// THREAD-SAFE MEMBER DATA
// All access to the following members must be protected by LOCK_LOCALS()
//
MESSAGEDATA *_pMsgData; // Linked list of messages
BOOL _fInSend; // True if we're inside SendToThread -
// needed to catch deadlock situations.
MESSAGEDATA * _pMsgReply; // Place where we need to put our reply
HANDLE _hResultEvt; // Event used to indicate that the result
// is ready.
};
|