From Ali Botorabi, "recently I ran into a problem with Microsoft's Appverifier while using OpenThreads on win32 platform. The Appverifier complained about an invalid thread handle during starting of a new thread. After looking closer into the problem it seemed that indeed a potential root of problem may be in the thread startup code. See the line below in Win32Thread.cpp (line number 347):

pd->tid.set( (void*)_beginthreadex(NULL,static_cast<unsigned>(pd->stackSize),ThreadPrivateActions::StartThread,static_cast<void *>(this),0,&ID));

the method "pd->tid.set" sets the thread id, however via the startup function "ThreadPrivateActions::StartThread" that thread id is used (see further down the call hierarchy the line "int status = SetThreadPriority( pd->tid.get(), prio);".

Until now I never ran into any problem in debug or release builds, though. It seems that furtunately the tid.set method was executed always before the tid.get method in the startup code. However, this may make trouble in the furture. A simple solution is the following: just replace the line above with following two lines:

    pd->tid.set( (void*)_beginthreadex(NULL,static_cast<unsigned>(pd->stackSize),ThreadPrivateActions::StartThread,static_cast<void *>(this),CREATE_SUSPENDED,&ID));
    ResumeThread(pd->tid.get());


The trick is just starting the thread in suspended mode so the StartThread function does not get executed and we can safely store the tid by pd->tid.set. Then start the Thread by calling ResumeThread."
This commit is contained in:
Robert Osfield 2014-05-02 09:11:16 +00:00
parent 35d73ea41c
commit 1f33e2a2a0

View File

@ -344,7 +344,8 @@ int Thread::start() {
pd->threadStartedBlock.reset();
pd->tid.set( (void*)_beginthreadex(NULL,static_cast<unsigned>(pd->stackSize),ThreadPrivateActions::StartThread,static_cast<void *>(this),0,&ID));
pd->tid.set( (void*)_beginthreadex(NULL,static_cast<unsigned>(pd->stackSize),ThreadPrivateActions::StartThread,static_cast<void *>(this),CREATE_SUSPENDED,&ID));
ResumeThread(pd->tid.get());
pd->uniqueId = (int)ID;