blob: 45adc01cf09edc214975d3c8e034022581d319a8 [file] [log] [blame]
Tristan Matthews0a329cc2013-07-17 13:20:14 -04001//------------------------------------------------------------------------------
2// File: MsgThrd.h
3//
4// Desc: DirectShow base classes - provides support for a worker thread
5// class to which one can asynchronously post messages.
6//
7// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
8//------------------------------------------------------------------------------
9
10
11// Message class - really just a structure.
12//
13class CMsg {
14public:
15 UINT uMsg;
16 DWORD dwFlags;
17 LPVOID lpParam;
18 CAMEvent *pEvent;
19
20 CMsg(UINT u, DWORD dw, __inout_opt LPVOID lp, __in_opt CAMEvent *pEvnt)
21 : uMsg(u), dwFlags(dw), lpParam(lp), pEvent(pEvnt) {}
22
23 CMsg()
24 : uMsg(0), dwFlags(0L), lpParam(NULL), pEvent(NULL) {}
25};
26
27// This is the actual thread class. It exports all the usual thread control
28// functions. The created thread is different from a normal WIN32 thread in
29// that it is prompted to perform particaular tasks by responding to messages
30// posted to its message queue.
31//
32class AM_NOVTABLE CMsgThread {
33private:
34 static DWORD WINAPI DefaultThreadProc(__inout LPVOID lpParam);
35 DWORD m_ThreadId;
36 HANDLE m_hThread;
37
38protected:
39
40 // if you want to override GetThreadMsg to block on other things
41 // as well as this queue, you need access to this
42 CGenericList<CMsg> m_ThreadQueue;
43 CCritSec m_Lock;
44 HANDLE m_hSem;
45 LONG m_lWaiting;
46
47public:
48 CMsgThread()
49 : m_ThreadId(0),
50 m_hThread(NULL),
51 m_lWaiting(0),
52 m_hSem(NULL),
53 // make a list with a cache of 5 items
54 m_ThreadQueue(NAME("MsgThread list"), 5)
55 {
56 }
57
58 ~CMsgThread();
59 // override this if you want to block on other things as well
60 // as the message loop
61 void virtual GetThreadMsg(__out CMsg *msg);
62
63 // override this if you want to do something on thread startup
64 virtual void OnThreadInit() {
65 };
66
67 BOOL CreateThread();
68
69 BOOL WaitForThreadExit(__out LPDWORD lpdwExitCode) {
70 if (m_hThread != NULL) {
71 WaitForSingleObject(m_hThread, INFINITE);
72 return GetExitCodeThread(m_hThread, lpdwExitCode);
73 }
74 return FALSE;
75 }
76
77 DWORD ResumeThread() {
78 return ::ResumeThread(m_hThread);
79 }
80
81 DWORD SuspendThread() {
82 return ::SuspendThread(m_hThread);
83 }
84
85 int GetThreadPriority() {
86 return ::GetThreadPriority(m_hThread);
87 }
88
89 BOOL SetThreadPriority(int nPriority) {
90 return ::SetThreadPriority(m_hThread, nPriority);
91 }
92
93 HANDLE GetThreadHandle() {
94 return m_hThread;
95 }
96
97 DWORD GetThreadId() {
98 return m_ThreadId;
99 }
100
101
102 void PutThreadMsg(UINT uMsg, DWORD dwMsgFlags,
103 __in_opt LPVOID lpMsgParam, __in_opt CAMEvent *pEvent = NULL) {
104 CAutoLock lck(&m_Lock);
105 CMsg* pMsg = new CMsg(uMsg, dwMsgFlags, lpMsgParam, pEvent);
106 m_ThreadQueue.AddTail(pMsg);
107 if (m_lWaiting != 0) {
108 ReleaseSemaphore(m_hSem, m_lWaiting, 0);
109 m_lWaiting = 0;
110 }
111 }
112
113 // This is the function prototype of the function that the client
114 // supplies. It is always called on the created thread, never on
115 // the creator thread.
116 //
117 virtual LRESULT ThreadMessageProc(
118 UINT uMsg, DWORD dwFlags, __inout_opt LPVOID lpParam, __in_opt CAMEvent *pEvent) = 0;
119};
120