user1092719
user1092719

Reputation: 523

Windows Threading - debug works release does not - attempting to get value from thread when it starts

I am attempting to get the ID of a thread for storage in a list of threads.

To do this I am launching a thread with a pointer to a long that will store the thread ID. The thread ID should be stored as soon as the thread function executes. The launching function should be able to continue once the ID is stored.

This code only seems to work in Debug mode but hangs in Release mode. I am using Visual C++ 2008 Express.

I need the code to work on Windows XP so unfortunately I cannot simply use GetThreadId as it is only supported on Windows Server 2003 and newer.

thread_wrapper* spawn_thread(void *entryPoint, void *params)
{
    thread_wrapper *newThread = calloc(1, sizeof(thread_wrapper));

    _beginthread(spawned_thread_wrapper_func, 0, &newThread->_win32ThreadID);

    while (newThread->_win32ThreadID == 0) ; // Hangs here in Release mode

    ... // Safely add thread to list using critical section

    return newThread;
}

void spawned_thread_wrapper_func(void *params)
{
    long *outThreadIDPtr = (long *)params;
    *outThreadIDPtr = GetCurrentThreadId();

    // spawn_thread function should now be able to add thread to list
    // but still hangs on while waiting loop in Release mode.
    // Works fine in Debug mode.

    ...
}

What is going wrong here?

Upvotes: 0

Views: 245

Answers (1)

WhozCraig
WhozCraig

Reputation: 66194

If you want the current thread id in that member variable, this is one way to do it using _beginthreadex(). That api gives you much more control over your thread-creation process, as well as a waitable handle for detecting thread-termination if desired. And note, the prototype for the thread proc and the implementation changes below are important.

thread_wrapper* spawn_thread(void *entryPoint, void *params)
{
    thread_wrapper *newThread = calloc(1, sizeof(thread_wrapper));

    // hThread is an OS thread handle you can wait on with 
    // wait functions like WaitForSingleObject.
    HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, 
            spawned_thread_wrapper_func, newThread,
            CREATE_SUSPENDED, &newThread->_win32ThreadID);

    // TODO: add new thread (which is created, but not started yet)
    //  to your list.


    // now resume the thread.
    ResumeThread(hThread);

    // if you don't need this any longer, close it, otherwise save it
    //  somewhere else (such as *before* the resume above, you can save
    //  it as a member of your thread_wrapper). No matter what, you have
    //  to close it eventually

    // CloseHandle(hThread);

    return newThread;
}

// note return value difference when using _beginthreadex.
unsigned int _stdcall spawned_thread_wrapper_func(void *params)
{
    thread_wrapper* p = params; // note: with MS you may have to cast this.

    // spawn_thread function should now be able to add thread to list
    // but still hangs on while waiting loop in Release mode.
    // Works fine in Debug mode.

    ...
}

Upvotes: 3

Related Questions