Everhart, Glenn From: David Cox [dcox@transoft.net] Sent: Tuesday, September 22, 1998 3:43 PM To: 'ntdev@atria.com' Subject: RE: [ntdev] Differences between return dwExitCode, ExitThread and AfxEndThread. I think I know what is going on; it's a result of using MFC to create the thread. When you call AfxEndThread() or return from your thread proc, the framework deletes the CWinThread object, and closes the thread handle contained therein. So after your Thread2() has terminated, the pThread2 memory isn't necessarily valid, and pThread2->m_hThread is an invalid handle. The API GetExitCode() is probably failing (returning zero) and not modifying your dwExitCode parameter. You're not aware that the API isn't giving you a valid exit code, because you're not checking the return value. When you call the ExitThread() API, you're short-circuiting the framework, causing memory and handle leaks. You shouldn't use ExitThread() unless you created the thread with CreateThread(). This is in fact documented in MSDN. It suggests these methods to accomplish what you're trying: Set the m_bAutoDelete data member to FALSE. This allows the CWinThread object to survive after the thread has been terminated. You can then access the m_hThread data member after the thread has been terminated. If you use this technique, however, you are responsible for destroying the CWinThread object as the framework will not automatically delete it for you. This is the preferred method. - or - Store the thread's handle separately. After the thread is created, copy its m_hThread data member (using ::DuplicateHandle) to another variable and access it through that variable. This way the object is deleted automatically upon termination and you can still find out why the thread terminated. Be careful that the thread does not terminate before you can duplicate the handle. The safest way to do this is to pass CREATE_SUSPENDED to AfxBeginThread, store the handle, and then resume the thread by calling ResumeThread. -- Dave Cox Transoft Networks > -----Original Message----- > From: Sudarshana_Gudipati [SMTP:SUDARSHANA_GUDIPATI@hht.satyam.com] > Sent: Monday, September 21, 1998 11:51 PM > To: ntdev@atria.com > Subject: [ntdev] Differences between return dwExitCode, ExitThread > and AfxEndThread. > > Hai, > I faced a situation where the which is calling ExitThread(dwExitCode) > compared to other two methods, signals the termination condition in all > the cases, wherein, the other two may not be. The following is the code: > Thread1() > { >         DWORD dwExitCode = STILL_ACTIVE; >   >         while(dwExitCocde == STILL_ACTIVE) >           ::GetExitCode(pThread2 -> m_hThread, &dwExitCode); >         //    Code continues... > } > Thread2() > { >         if(SomeEvent occured to exit the thread) >               ExitThread(SUCCESS);        // always Thread1 gets released >         >         // Instead of ExitThread(..), if return SUCCESS or > AfxEndThread(...)  // are used, Thread1 may not be able to come out of the > polling code. > } > Note : Both the threads have been spawned off by a call to > AfxBeginThread(...); > Can any one explain why is this behaviour and what is the reason? > Pl. note that I'm not expecting the alternative method, rather, I'm > looking for the reason for this misterious behaviour (atleast for me). >         > Thanks in advance. > Sudarsan. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ To unsubscribe, send email to ntdev-request@atria.com with body UNSUBSCRIBE (the subject is ignored). ]