Reinstnate the call to TerminateThread inside ExceptionHandler destructor and put

the graceful code inside a #ifdef.

The problem is:
If ExceptionHandler is created and destroyed in DllMain, then the previous change to
remove the call to TerminateThread will lead to a deadlock. This is because inside
DllMain the loader lock is acquired, and the previous change waits for the handler
thread to exit in the destructor, that is with the loader lock acquired. But the
handler thread cannot finish until it gets the loader lock to call DllMain for
THREAD_DETACH.

With this change, we add conditional compilation so that clients that want to
avoid the call to terminate thread can do it by defining the appropriate preprocessor
variable.



git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@309 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
doshimun 2009-01-20 20:45:28 +00:00
parent 104e4e0114
commit c9944d96e8

View File

@ -272,13 +272,20 @@ ExceptionHandler::~ExceptionHandler() {
// Some of the objects were only initialized if out of process
// registration was not done.
if (!IsOutOfProcess()) {
#ifdef BREAKPAD_NO_TERMINATE_THREAD
// Clean up the handler thread and synchronization primitives. The handler
// thread is either waiting on the semaphore to handle a crash or it is
// handling a crash. Coming out of the wait is fast but wait more in the
// eventuality a crash is handled.
// eventuality a crash is handled. This compilation option results in a
// deadlock if the exception handler is destroyed while executing code
// inside DllMain.
is_shutdown_ = true;
ReleaseSemaphore(handler_start_semaphore_, 1, NULL);
WaitForSingleObject(handler_thread_, kWaitForHandlerThreadMs);
#else
TerminateThread(handler_thread_, 1);
#endif // BREAKPAD_NO_TERMINATE_THREAD
DeleteCriticalSection(&handler_critical_section_);
CloseHandle(handler_start_semaphore_);
CloseHandle(handler_finish_semaphore_);
@ -321,6 +328,8 @@ DWORD ExceptionHandler::ExceptionHandlerThreadMain(void* lpParameter) {
}
}
// This statement is not reached when the thread is unconditionally
// terminated by the ExceptionHandler destructor.
return 0;
}