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;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 |