mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1200614 - Protect the capture engines array from concurrent access (during shutdown). r=jesup
This commit is contained in:
parent
deee8c45c6
commit
95f412e884
@ -324,21 +324,24 @@ CamerasParent::CloseEngines()
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < CaptureEngine::MaxEngine; i++) {
|
||||
if (mEngines[i].mEngineIsRunning) {
|
||||
LOG(("Being closed down while engine %d is running!", i));
|
||||
}
|
||||
if (mEngines[i].mPtrViERender) {
|
||||
mEngines[i].mPtrViERender->Release();
|
||||
mEngines[i].mPtrViERender = nullptr;
|
||||
}
|
||||
if (mEngines[i].mPtrViECapture) {
|
||||
mEngines[i].mPtrViECapture->Release();
|
||||
mEngines[i].mPtrViECapture = nullptr;
|
||||
}
|
||||
if(mEngines[i].mPtrViEBase) {
|
||||
mEngines[i].mPtrViEBase->Release();
|
||||
mEngines[i].mPtrViEBase = nullptr;
|
||||
{
|
||||
MutexAutoLock lock(mEngineMutex);
|
||||
for (int i = 0; i < CaptureEngine::MaxEngine; i++) {
|
||||
if (mEngines[i].mEngineIsRunning) {
|
||||
LOG(("Being closed down while engine %d is running!", i));
|
||||
}
|
||||
if (mEngines[i].mPtrViERender) {
|
||||
mEngines[i].mPtrViERender->Release();
|
||||
mEngines[i].mPtrViERender = nullptr;
|
||||
}
|
||||
if (mEngines[i].mPtrViECapture) {
|
||||
mEngines[i].mPtrViECapture->Release();
|
||||
mEngines[i].mPtrViECapture = nullptr;
|
||||
}
|
||||
if(mEngines[i].mPtrViEBase) {
|
||||
mEngines[i].mPtrViEBase->Release();
|
||||
mEngines[i].mPtrViEBase = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -373,6 +376,7 @@ CamerasParent::RecvNumberOfCaptureDevices(const int& aCapEngine)
|
||||
nsRefPtr<CamerasParent> self(this);
|
||||
nsRefPtr<nsRunnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, aCapEngine]() -> nsresult {
|
||||
MutexAutoLock lock(self->mEngineMutex);
|
||||
int num = self->mEngines[aCapEngine].mPtrViECapture->NumberOfCaptureDevices();
|
||||
nsRefPtr<nsIRunnable> ipc_runnable =
|
||||
media::NewRunnableFrom([self, num]() -> nsresult {
|
||||
@ -412,6 +416,7 @@ CamerasParent::RecvNumberOfCapabilities(const int& aCapEngine,
|
||||
nsRefPtr<CamerasParent> self(this);
|
||||
nsRefPtr<nsRunnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, unique_id, aCapEngine]() -> nsresult {
|
||||
MutexAutoLock lock(self->mEngineMutex);
|
||||
int num =
|
||||
self->mEngines[aCapEngine].mPtrViECapture->NumberOfCapabilities(
|
||||
unique_id.get(),
|
||||
@ -456,6 +461,7 @@ CamerasParent::RecvGetCaptureCapability(const int &aCapEngine,
|
||||
nsRefPtr<nsRunnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, unique_id, aCapEngine, num]() -> nsresult {
|
||||
webrtc::CaptureCapability webrtcCaps;
|
||||
MutexAutoLock lock(self->mEngineMutex);
|
||||
int error = self->mEngines[aCapEngine].mPtrViECapture->GetCaptureCapability(
|
||||
unique_id.get(), MediaEngineSource::kMaxUniqueIdLength, num, webrtcCaps);
|
||||
nsRefPtr<nsIRunnable> ipc_runnable =
|
||||
@ -510,7 +516,7 @@ CamerasParent::RecvGetCaptureDevice(const int& aCapEngine,
|
||||
char deviceUniqueId[MediaEngineSource::kMaxUniqueIdLength];
|
||||
nsCString name;
|
||||
nsCString uniqueId;
|
||||
|
||||
MutexAutoLock lock(self->mEngineMutex);
|
||||
int error =
|
||||
self->mEngines[aCapEngine].mPtrViECapture->GetCaptureDevice(aListNumber,
|
||||
deviceName,
|
||||
@ -559,6 +565,7 @@ CamerasParent::RecvAllocateCaptureDevice(const int& aCapEngine,
|
||||
nsRefPtr<nsRunnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, aCapEngine, unique_id]() -> nsresult {
|
||||
int numdev;
|
||||
MutexAutoLock lock(self->mEngineMutex);
|
||||
int error = self->mEngines[aCapEngine].mPtrViECapture->AllocateCaptureDevice(
|
||||
unique_id.get(), MediaEngineSource::kMaxUniqueIdLength, numdev);
|
||||
nsRefPtr<nsIRunnable> ipc_runnable =
|
||||
@ -597,6 +604,7 @@ CamerasParent::RecvReleaseCaptureDevice(const int& aCapEngine,
|
||||
nsRefPtr<nsRunnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, aCapEngine, numdev]() -> nsresult {
|
||||
LOG(("RecvReleaseCamera device nr %d", numdev));
|
||||
MutexAutoLock lock(self->mEngineMutex);
|
||||
int error = self->mEngines[aCapEngine].mPtrViECapture->ReleaseCaptureDevice(numdev);
|
||||
nsRefPtr<nsIRunnable> ipc_runnable =
|
||||
media::NewRunnableFrom([self, error, numdev]() -> nsresult {
|
||||
@ -639,35 +647,41 @@ CamerasParent::RecvStartCapture(const int& aCapEngine,
|
||||
nsRefPtr<CamerasParent> self(this);
|
||||
nsRefPtr<nsRunnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, aCapEngine, capnum, ipcCaps]() -> nsresult {
|
||||
MutexAutoLock lock(self->mCallbackMutex);
|
||||
auto cbh = self->mCallbacks.AppendElement(
|
||||
new CallbackHelper(static_cast<CaptureEngine>(aCapEngine), capnum, self));
|
||||
auto render = static_cast<webrtc::ExternalRenderer*>(*cbh);
|
||||
|
||||
EngineHelper* helper = &self->mEngines[aCapEngine];
|
||||
|
||||
int error =
|
||||
helper->mPtrViERender->AddRenderer(capnum, webrtc::kVideoI420, render);
|
||||
|
||||
if (!error) {
|
||||
error = helper->mPtrViERender->StartRender(capnum);
|
||||
CallbackHelper** cbh;
|
||||
webrtc::ExternalRenderer* render;
|
||||
EngineHelper* helper;
|
||||
int error;
|
||||
{
|
||||
MutexAutoLock lockCallback(self->mCallbackMutex);
|
||||
cbh = self->mCallbacks.AppendElement(
|
||||
new CallbackHelper(static_cast<CaptureEngine>(aCapEngine), capnum, self));
|
||||
render = static_cast<webrtc::ExternalRenderer*>(*cbh);
|
||||
}
|
||||
{
|
||||
MutexAutoLock lockEngine(self->mEngineMutex);
|
||||
helper = &self->mEngines[aCapEngine];
|
||||
error =
|
||||
helper->mPtrViERender->AddRenderer(capnum, webrtc::kVideoI420, render);
|
||||
|
||||
webrtc::CaptureCapability capability;
|
||||
capability.width = ipcCaps.width();
|
||||
capability.height = ipcCaps.height();
|
||||
capability.maxFPS = ipcCaps.maxFPS();
|
||||
capability.expectedCaptureDelay = ipcCaps.expectedCaptureDelay();
|
||||
capability.rawType = static_cast<webrtc::RawVideoType>(ipcCaps.rawType());
|
||||
capability.codecType = static_cast<webrtc::VideoCodecType>(ipcCaps.codecType());
|
||||
capability.interlaced = ipcCaps.interlaced();
|
||||
if (!error) {
|
||||
error = helper->mPtrViERender->StartRender(capnum);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
error = helper->mPtrViECapture->StartCapture(capnum, capability);
|
||||
}
|
||||
webrtc::CaptureCapability capability;
|
||||
capability.width = ipcCaps.width();
|
||||
capability.height = ipcCaps.height();
|
||||
capability.maxFPS = ipcCaps.maxFPS();
|
||||
capability.expectedCaptureDelay = ipcCaps.expectedCaptureDelay();
|
||||
capability.rawType = static_cast<webrtc::RawVideoType>(ipcCaps.rawType());
|
||||
capability.codecType = static_cast<webrtc::VideoCodecType>(ipcCaps.codecType());
|
||||
capability.interlaced = ipcCaps.interlaced();
|
||||
|
||||
if (!error) {
|
||||
helper->mEngineIsRunning = true;
|
||||
if (!error) {
|
||||
error = helper->mPtrViECapture->StartCapture(capnum, capability);
|
||||
}
|
||||
if (!error) {
|
||||
helper->mEngineIsRunning = true;
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<nsIRunnable> ipc_runnable =
|
||||
@ -704,11 +718,13 @@ CamerasParent::RecvStopCapture(const int& aCapEngine,
|
||||
nsRefPtr<CamerasParent> self(this);
|
||||
nsRefPtr<nsRunnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, aCapEngine, capnum]() -> nsresult {
|
||||
self->mEngines[aCapEngine].mPtrViECapture->StopCapture(capnum);
|
||||
self->mEngines[aCapEngine].mPtrViERender->StopRender(capnum);
|
||||
self->mEngines[aCapEngine].mPtrViERender->RemoveRenderer(capnum);
|
||||
self->mEngines[aCapEngine].mEngineIsRunning = false;
|
||||
|
||||
{
|
||||
MutexAutoLock lock(self->mEngineMutex);
|
||||
self->mEngines[aCapEngine].mPtrViECapture->StopCapture(capnum);
|
||||
self->mEngines[aCapEngine].mPtrViERender->StopRender(capnum);
|
||||
self->mEngines[aCapEngine].mPtrViERender->RemoveRenderer(capnum);
|
||||
self->mEngines[aCapEngine].mEngineIsRunning = false;
|
||||
}
|
||||
MutexAutoLock lock(self->mCallbackMutex);
|
||||
for (unsigned int i = 0; i < self->mCallbacks.Length(); i++) {
|
||||
if (self->mCallbacks[i]->mCapEngine == aCapEngine
|
||||
@ -739,11 +755,14 @@ void CamerasParent::DoShutdown()
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
CloseEngines();
|
||||
|
||||
for (int i = 0; i < CaptureEngine::MaxEngine; i++) {
|
||||
if (mEngines[i].mEngine) {
|
||||
mEngines[i].mEngine->SetTraceCallback(nullptr);
|
||||
webrtc::VideoEngine::Delete(mEngines[i].mEngine);
|
||||
mEngines[i].mEngine = nullptr;
|
||||
{
|
||||
MutexAutoLock lock(mEngineMutex);
|
||||
for (int i = 0; i < CaptureEngine::MaxEngine; i++) {
|
||||
if (mEngines[i].mEngine) {
|
||||
mEngines[i].mEngine->SetTraceCallback(nullptr);
|
||||
webrtc::VideoEngine::Delete(mEngines[i].mEngine);
|
||||
mEngines[i].mEngine = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -774,6 +793,7 @@ CamerasParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
|
||||
CamerasParent::CamerasParent()
|
||||
: mCallbackMutex("CamerasParent.mCallbackMutex"),
|
||||
mEngineMutex("CamerasParent.mEngineMutex"),
|
||||
mShmemPool(CaptureEngine::MaxEngine),
|
||||
mVideoCaptureThread(nullptr),
|
||||
mChildIsAlive(true),
|
||||
|
@ -122,6 +122,8 @@ protected:
|
||||
nsTArray<CallbackHelper*> mCallbacks;
|
||||
// Protects the callback arrays
|
||||
Mutex mCallbackMutex;
|
||||
// Protects the engines array
|
||||
Mutex mEngineMutex;
|
||||
|
||||
// image buffers
|
||||
mozilla::ShmemPool mShmemPool;
|
||||
|
Loading…
Reference in New Issue
Block a user