This CL is an attempt to remove a crash we can see when closing down VoiceEgine.

It can happen that the capture thread tries to access an invalid object after StopPlayout has been called.

I have also extended the usage of the new ScopedCOMInitializer to all threads. See this step as code cleanup.
Review URL: http://webrtc-codereview.appspot.com/239014

git-svn-id: http://webrtc.googlecode.com/svn/trunk@813 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
henrika@webrtc.org
2011-10-25 11:03:28 +00:00
parent a6c23357c0
commit bdb55c806f

View File

@ -186,7 +186,6 @@ bool AudioDeviceWindowsCore::CoreAudioIsSupported()
bool MMDeviceIsAvailable(false); bool MMDeviceIsAvailable(false);
bool coreAudioIsSupported(false); bool coreAudioIsSupported(false);
bool coUninitializeIsRequired(true);
HRESULT hr(S_OK); HRESULT hr(S_OK);
TCHAR buf[MAXERRORLENGTH]; TCHAR buf[MAXERRORLENGTH];
@ -199,8 +198,8 @@ bool AudioDeviceWindowsCore::CoreAudioIsSupported()
// wrapper also ensures that each call to CoInitializeEx is balanced // wrapper also ensures that each call to CoInitializeEx is balanced
// by a corresponding call to CoUninitialize. // by a corresponding call to CoUninitialize.
// //
ScopedCOMInitializer com_init(ScopedCOMInitializer::kMTA); ScopedCOMInitializer comInit(ScopedCOMInitializer::kMTA);
if (!com_init.succeeded()) { if (!comInit.succeeded()) {
// Things will work even if an STA thread is calling this method but we // Things will work even if an STA thread is calling this method but we
// want to ensure that MTA is used and therefore return false here. // want to ensure that MTA is used and therefore return false here.
return false; return false;
@ -3114,9 +3113,8 @@ WebRtc_Word32 AudioDeviceWindowsCore::StopPlayout()
WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
"webrtc_core_audio_render_thread is now closed"); "webrtc_core_audio_render_thread is now closed");
// Ensure that the thread has released these interfaces properly SAFE_RELEASE(_ptrClientOut);
assert(NULL == _ptrClientOut); SAFE_RELEASE(_ptrRenderClient);
assert(NULL == _ptrRenderClient);
_playIsInitialized = false; _playIsInitialized = false;
_playing = false; _playing = false;
@ -3427,12 +3425,12 @@ DWORD AudioDeviceWindowsCore::DoRenderThread()
LARGE_INTEGER t2; LARGE_INTEGER t2;
WebRtc_Word32 time(0); WebRtc_Word32 time(0);
hr = CoInitializeEx(NULL, COM_THREADING_MODEL); // Initialize COM as MTA in this thread.
if (FAILED(hr)) ScopedCOMInitializer comInit(ScopedCOMInitializer::kMTA);
{ if (!comInit.succeeded()) {
_TraceCOMError(hr); WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "unable to initialize COM in render thread"); "failed to initialize COM in render thread");
return hr; return -1;
} }
_SetThreadName(-1, "webrtc_core_audio_render_thread"); _SetThreadName(-1, "webrtc_core_audio_render_thread");
@ -3665,10 +3663,6 @@ Exit:
WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "_Rendering thread is now terminated properly"); WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "_Rendering thread is now terminated properly");
} }
SAFE_RELEASE(_ptrClientOut);
SAFE_RELEASE(_ptrRenderClient);
CoUninitialize();
return (DWORD)hr; return (DWORD)hr;
} }
@ -3677,15 +3671,6 @@ DWORD AudioDeviceWindowsCore::InitCaptureThreadPriority()
HRESULT hr = S_OK; HRESULT hr = S_OK;
_hMmTask = NULL; _hMmTask = NULL;
hr = CoInitializeEx(NULL, COM_THREADING_MODEL);
if (FAILED(hr))
{
_TraceCOMError(hr);
WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
"unable to initialize COM in capture thread");
return hr;
}
_SetThreadName(-1, "webrtc_core_audio_capture_thread"); _SetThreadName(-1, "webrtc_core_audio_capture_thread");
// Use Multimedia Class Scheduler Service (MMCSS) to boost the thread // Use Multimedia Class Scheduler Service (MMCSS) to boost the thread
@ -3735,6 +3720,14 @@ DWORD AudioDeviceWindowsCore::DoCaptureThreadPollDMO()
assert(_mediaBuffer != NULL); assert(_mediaBuffer != NULL);
bool keepRecording = true; bool keepRecording = true;
// Initialize COM as MTA in this thread.
ScopedCOMInitializer comInit(ScopedCOMInitializer::kMTA);
if (!comInit.succeeded()) {
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
"failed to initialize COM in polling DMO thread");
return -1;
}
HRESULT hr = InitCaptureThreadPriority(); HRESULT hr = InitCaptureThreadPriority();
if (FAILED(hr)) if (FAILED(hr))
{ {
@ -3861,7 +3854,6 @@ DWORD AudioDeviceWindowsCore::DoCaptureThreadPollDMO()
"Capturing thread is now terminated properly"); "Capturing thread is now terminated properly");
} }
CoUninitialize();
return hr; return hr;
} }
@ -3891,6 +3883,14 @@ DWORD AudioDeviceWindowsCore::DoCaptureThread()
_readSamples = 0; _readSamples = 0;
// Initialize COM as MTA in this thread.
ScopedCOMInitializer comInit(ScopedCOMInitializer::kMTA);
if (!comInit.succeeded()) {
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
"failed to initialize COM in capture thread");
return -1;
}
hr = InitCaptureThreadPriority(); hr = InitCaptureThreadPriority();
if (FAILED(hr)) if (FAILED(hr))
{ {
@ -4171,7 +4171,6 @@ Exit:
delete [] syncBuffer; delete [] syncBuffer;
} }
CoUninitialize();
return (DWORD)hr; return (DWORD)hr;
} }