121 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			121 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | //------------------------------------------------------------------------------
 | ||
|  | // File: MsgThrd.h
 | ||
|  | //
 | ||
|  | // Desc: DirectShow base classes - provides support for a worker thread 
 | ||
|  | //       class to which one can asynchronously post messages.
 | ||
|  | //
 | ||
|  | // Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.
 | ||
|  | //------------------------------------------------------------------------------
 | ||
|  | 
 | ||
|  | 
 | ||
|  | // Message class - really just a structure.
 | ||
|  | //
 | ||
|  | class CMsg { | ||
|  | public: | ||
|  |     UINT uMsg; | ||
|  |     DWORD dwFlags; | ||
|  |     LPVOID lpParam; | ||
|  |     CAMEvent *pEvent; | ||
|  | 
 | ||
|  |     CMsg(UINT u, DWORD dw, __inout_opt LPVOID lp, __in_opt CAMEvent *pEvnt) | ||
|  |         : uMsg(u), dwFlags(dw), lpParam(lp), pEvent(pEvnt) {} | ||
|  | 
 | ||
|  |     CMsg() | ||
|  |         : uMsg(0), dwFlags(0L), lpParam(NULL), pEvent(NULL) {} | ||
|  | }; | ||
|  | 
 | ||
|  | // This is the actual thread class.  It exports all the usual thread control
 | ||
|  | // functions.  The created thread is different from a normal WIN32 thread in
 | ||
|  | // that it is prompted to perform particaular tasks by responding to messages
 | ||
|  | // posted to its message queue.
 | ||
|  | //
 | ||
|  | class AM_NOVTABLE CMsgThread { | ||
|  | private: | ||
|  |     static DWORD WINAPI DefaultThreadProc(__inout LPVOID lpParam); | ||
|  |     DWORD               m_ThreadId; | ||
|  |     HANDLE              m_hThread; | ||
|  | 
 | ||
|  | protected: | ||
|  | 
 | ||
|  |     // if you want to override GetThreadMsg to block on other things
 | ||
|  |     // as well as this queue, you need access to this
 | ||
|  |     CGenericList<CMsg>        m_ThreadQueue; | ||
|  |     CCritSec                  m_Lock; | ||
|  |     HANDLE                    m_hSem; | ||
|  |     LONG                      m_lWaiting; | ||
|  | 
 | ||
|  | public: | ||
|  |     CMsgThread() | ||
|  |         : m_ThreadId(0), | ||
|  |         m_hThread(NULL), | ||
|  |         m_lWaiting(0), | ||
|  |         m_hSem(NULL), | ||
|  |         // make a list with a cache of 5 items
 | ||
|  |         m_ThreadQueue(NAME("MsgThread list"), 5) | ||
|  |         { | ||
|  |         } | ||
|  | 
 | ||
|  |     ~CMsgThread(); | ||
|  |     // override this if you want to block on other things as well
 | ||
|  |     // as the message loop
 | ||
|  |     void virtual GetThreadMsg(__out CMsg *msg); | ||
|  | 
 | ||
|  |     // override this if you want to do something on thread startup
 | ||
|  |     virtual void OnThreadInit() { | ||
|  |     }; | ||
|  | 
 | ||
|  |     BOOL CreateThread(); | ||
|  | 
 | ||
|  |     BOOL WaitForThreadExit(__out LPDWORD lpdwExitCode) { | ||
|  |         if (m_hThread != NULL) { | ||
|  |             WaitForSingleObject(m_hThread, INFINITE); | ||
|  |             return GetExitCodeThread(m_hThread, lpdwExitCode); | ||
|  |         } | ||
|  |         return FALSE; | ||
|  |     } | ||
|  | 
 | ||
|  |     DWORD ResumeThread() { | ||
|  |         return ::ResumeThread(m_hThread); | ||
|  |     } | ||
|  | 
 | ||
|  |     DWORD SuspendThread() { | ||
|  |         return ::SuspendThread(m_hThread); | ||
|  |     } | ||
|  | 
 | ||
|  |     int GetThreadPriority() { | ||
|  |         return ::GetThreadPriority(m_hThread); | ||
|  |     } | ||
|  | 
 | ||
|  |     BOOL SetThreadPriority(int nPriority) { | ||
|  |         return ::SetThreadPriority(m_hThread, nPriority); | ||
|  |     } | ||
|  | 
 | ||
|  |     HANDLE GetThreadHandle() { | ||
|  |         return m_hThread; | ||
|  |     } | ||
|  | 
 | ||
|  |     DWORD GetThreadId() { | ||
|  |         return m_ThreadId; | ||
|  |     } | ||
|  | 
 | ||
|  | 
 | ||
|  |     void PutThreadMsg(UINT uMsg, DWORD dwMsgFlags, | ||
|  |                       __in_opt LPVOID lpMsgParam, __in_opt CAMEvent *pEvent = NULL) { | ||
|  |         CAutoLock lck(&m_Lock); | ||
|  |         CMsg* pMsg = new CMsg(uMsg, dwMsgFlags, lpMsgParam, pEvent); | ||
|  |         m_ThreadQueue.AddTail(pMsg); | ||
|  |         if (m_lWaiting != 0) { | ||
|  |             ReleaseSemaphore(m_hSem, m_lWaiting, 0); | ||
|  |             m_lWaiting = 0; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     // This is the function prototype of the function that the client
 | ||
|  |     // supplies.  It is always called on the created thread, never on
 | ||
|  |     // the creator thread.
 | ||
|  |     //
 | ||
|  |     virtual LRESULT ThreadMessageProc( | ||
|  |         UINT uMsg, DWORD dwFlags, __inout_opt LPVOID lpParam, __in_opt CAMEvent *pEvent) = 0; | ||
|  | }; | ||
|  | 
 |