summaryrefslogtreecommitdiffstats
path: root/thirdparties/win32/include/directshow/msgthrd.h
blob: 208f03c82d6e62c5ddc864f09d1cd7dfb5c8d657 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//------------------------------------------------------------------------------
// 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;
};

OpenPOWER on IntegriCloud