0
votes

I have a loop generating threads via AfxBeginThread, which stores the CWinThread pointers in an array. In each iteration, I check the thread is not null and store the thread's handle in another array.

const unsigned int maxThreads = 2;
CWinThread* threads[maxThreads];
HANDLE* handles[maxThreads];
for(unsigned int threadId=0; threadId < maxThreads; ++threadId)
{
    threads[threadId] = AfxBeginThread(endToEndProc, &threadId,
                                            0,0,CREATE_SUSPENDED);
    if(threads[threadId] == NULL) 
    {
        // die carefully
    }
    threads[threadId]->m_bAutoDelete = FALSE;
    handles[threadId] = &threads[threadId]->m_hThread;
    ::ResumeThread(handles[threadId]);
}

DWORD result = ::WaitForMultipleObjects(maxThreads, handles[0], 
                                            TRUE, 20000*maxThreads);

But WaitForMultipleObjects always returns with WAIT_FAILED, and GetLastError yields 6 for invalid handle. Either the test for the AfxBeginThread return is insufficient to guarantee the thread was created successfully and the handle will be valid, or the handle is becoming invalid before the WaitForMultipleObjects call, which I thought would be prevented by setting m_bAutoDelete to FALSE.

Is there a better way to wait on multiple threads when they are created by AfxBeginThread?

Note that it is fine when maxThreads=1.

1

1 Answers

5
votes

handles[0] points to something that has ONE valid handle and some data possibly following it. maxThreads instead suggests that array should have two handles there one after another. Hence the error.

This is what you want instead:

HANDLE handles[maxThreads];
//...
handles[threadId] = threads[threadId]->m_hThread;
//...
WaitForMultipleObjects(maxThreads, handles, ...