|
|
//------------------------------------------------------------------------------
// 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, LPVOID lp, 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(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(CMsg *msg);
// override this if you want to do something on thread startup
virtual void OnThreadInit() { };
BOOL CreateThread();
BOOL WaitForThreadExit(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, LPVOID lpMsgParam, 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, LPVOID lpParam, CAMEvent *pEvent) = 0; };
|