505HPC6Z06
505HPC6Z06

Reputation: 183

Need help passing Windows Event HANDLE by reference to a class

The program idea is to run a loop in thread procedure Setxxx() and at the end of the loop, wait on an event. Once the event fires, the loop resumes.

This Setxxx() function is in a class and its caller creates the event, the thread and passes the event to the class constructor.

I thought if I passed in a pointer to the HANDLE, I could call ResetEvent to unblock the thread. But the problem is the WaitForSingleObjectEx function returns w/out waiting. Its return code is 6 (DWORD) invalid handle.

How can I pass in the handle such that I can control the thread by unblocking with ResetEvent?

// header file
class CPropertyMarker {
public:
    CPropertyMarker(HANDLE **hThreadSignalEvent);
    void Setxxx();
private:
    bool m_Run;
    HANDLE* m_hThreadSignalEvent;
};

// class file
CPropertyMarker::CPropertyMarker(HANDLE **hThreadSignalEvent) {
    m_hThreadSignalEvent = *hThreadSignalEvent;
}
void CPropertyMarker::Setxxx() {
    DWORD retVal = 0;
    while(m_Run) {
        try {
            // statements snipped
        }
        catch(exception){}
        ResetEvent(m_hThreadSignalEvent);
        WaitForSingleObjectEx(&m_hThreadSignalEvent, INFINITE, false);
    }
}

// caller 
m_hEventMainThread  = (HANDLE*)CreateEvent(NULL, true, true, L"xxx-adsfsdfblah_yyy");
m_PropMarker        = new CPropertyMarker(&m_hEventMainThread);
m_PropMarker->SetRunState(true);
m_hThreadMain       = CreateThread(NULL, 0, &CFromMyClass::Setxxx, (LPVOID)m_PropMarker, 0, &m_ThreadMainId); 

Upvotes: 2

Views: 967

Answers (2)

Dickberto
Dickberto

Reputation: 41

Actually,

WaitForSingleObjectEx(&m_hThreadSignalEvent, INFINITE, false);

should be

WaitForSingleObjectEx(*m_hThreadSignalEvent, INFINITE, false);

I would also add that your sample does not need to be using HANDLE pointers (HANDLE *) at all.

Upvotes: 3

Jonathan Potter
Jonathan Potter

Reputation: 37122

m_hThreadSignalEvent is a HANDLE* so you need to dereference it. You would need to change your code to:

   ResetEvent(*m_hThreadSignalEvent);
   WaitForSingleObjectEx(*m_hThreadSignalEvent, INFINITE, false);

However your CPropertyMarker constructor is also odd, as it takes a HANDLE**, and dereferences it to get a HANDLE* which is almost certainly not correct. You seem to have too many levels of indirection. A HANDLE is a pointer in its own right, you very rarely would need to use HANDLE* anywhere.

I would look at changing your code to:

// header file
class CPropertyMarker {
public:
    CPropertyMarker(HANDLE hThreadSignalEvent);
    void Setxxx();
private:
    bool m_Run;
    HANDLE m_hThreadSignalEvent;
};

// class file
CPropertyMarker::CPropertyMarker(HANDLE hThreadSignalEvent) {
    m_hThreadSignalEvent = hThreadSignalEvent;
}
void CPropertyMarker::Setxxx() {
    DWORD retVal = 0;
    while(m_Run) {
        try {
            // statements snipped
        }
        catch(exception){}
        ResetEvent(m_hThreadSignalEvent);
        WaitForSingleObjectEx(m_hThreadSignalEvent, INFINITE, false);
    }
}

// caller 
m_hEventMainThread  = CreateEvent(NULL, true, true, L"xxx-adsfsdfblah_yyy");
m_PropMarker        = new CPropertyMarker(m_hEventMainThread);

Upvotes: 5

Related Questions