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.

150 lines
5.0 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: thrdcomm.h
  7. //
  8. // Contents: Contains the inter-thread communication class
  9. //
  10. //----------------------------------------------------------------------------
  11. //****************************************************************************
  12. //
  13. // Forward declarations
  14. //
  15. //****************************************************************************
  16. class CThreadComm;
  17. //****************************************************************************
  18. //
  19. // Classes
  20. //
  21. //****************************************************************************
  22. //+---------------------------------------------------------------------------
  23. //
  24. // Class: CThreadComm (ctc)
  25. //
  26. // Purpose: Base class which handles cross-thread communication. This
  27. // is the only class with methods that can safely be called
  28. // by any thread. All other classes must have their methods
  29. // called by their owning thread (except the ctor/dtor and Init
  30. // which are called by the creating thread).
  31. //
  32. //----------------------------------------------------------------------------
  33. class CThreadComm : public IUnknown, public CThreadLock
  34. {
  35. public:
  36. DECLARE_MEMCLEAR_NEW_DELETE();
  37. // Thread-unsafe member functions - can only be called by owning (or
  38. // creating) thread.
  39. CThreadComm();
  40. ~CThreadComm();
  41. HRESULT StartThread(void * pvParams);
  42. BOOL Shutdown(CThreadComm * pTarget);
  43. static DWORD TempThreadRoutine(LPVOID pvParam);
  44. virtual DWORD ThreadMain() = 0;
  45. // Used to tell StartThread that the new thread is going and has picked
  46. // up all of its parameters.
  47. // If fSuccess is false, then the thread will be terminating
  48. // immediatly, and StartThread() will wait for it to do so.
  49. void ThreadStarted(HRESULT hrThread) {
  50. _hrThread = hrThread;
  51. SetEvent(_hThreadReady); // Signal the other thread
  52. ::Sleep(100); // Yield to the other thread
  53. }
  54. BOOL GetNextMsg(THREADMSG *tm, void * pData, DWORD *cbData);
  55. void Reply(DWORD dwReply);
  56. void SetName(LPCSTR szName);
  57. // -----------------------------------------------------------------
  58. //
  59. // Thread-safe member functions - can be called by any thread.
  60. HANDLE hThread() { return _hThread; }
  61. void PostToThread(CThreadComm *pTarget, THREADMSG tm, void * pData = NULL, DWORD cbData = 0);
  62. DWORD SendToThread(CThreadComm *pTarget, THREADMSG tm, void * pData = NULL, DWORD cbData = 0);
  63. // End of thread-safe member list
  64. //
  65. // -----------------------------------------------------------------
  66. protected:
  67. virtual BOOL Init();
  68. //
  69. // Every method on objects that derive from CThreadComm should have
  70. // VERIFY_THREAD at the beginning. VERIFY_THREAD ensures that the proper
  71. // thread is calling the method (i.e. it ensure that proper apartment rules
  72. // are being followed.)
  73. //
  74. inline void VERIFY_THREAD() { Assert(GetCurrentThreadId() == _dwThreadId); }
  75. HANDLE _hThreadReady; // Event signaled when the new thread has set its return value
  76. HANDLE _hCommEvent; // Event signaled when there is a message
  77. DWORD _dwThreadId;
  78. HANDLE _hThread;
  79. void * _pvParams;
  80. HRESULT _hrThread; // The new thread sets this for initial success/failure.
  81. private:
  82. //
  83. // MSGDATABUFSIZE: Max size of a thread message. The -40 is to keep the
  84. // MESSAGEDATA struct below 1K.
  85. //
  86. #define MSGDATABUFSIZE (1024 - 40)
  87. //
  88. // MESSAGEDATA: All the data associated with a thread message.
  89. //
  90. struct MESSAGEDATA
  91. {
  92. MESSAGEDATA *pNext;
  93. THREADMSG tmMessage;
  94. DWORD dwResult;
  95. HANDLE hResultEvt;
  96. DWORD cbData;
  97. BYTE bData[MSGDATABUFSIZE];
  98. };
  99. #if DBG == 1
  100. typedef struct tagTHREADNAME_INFO
  101. {
  102. DWORD dwType; // == 0x1000
  103. LPCSTR szName;
  104. DWORD dwThreadID;
  105. DWORD dwFlags;
  106. } THREADNAME_INFO;
  107. #endif
  108. DWORD SendHelper(THREADMSG tm,
  109. void * pData,
  110. DWORD cbData,
  111. BOOL fSend,
  112. HANDLE hResultEvt);
  113. // ***************************
  114. // THREAD-SAFE MEMBER DATA
  115. // All access to the following members must be protected by LOCK_LOCALS()
  116. //
  117. MESSAGEDATA *_pMsgData; // Linked list of messages
  118. BOOL _fInSend; // True if we're inside SendToThread -
  119. // needed to catch deadlock situations.
  120. MESSAGEDATA * _pMsgReply; // Place where we need to put our reply
  121. HANDLE _hResultEvt; // Event used to indicate that the result
  122. // is ready.
  123. };