Bug 1155939 - GMPServiceParent fixes for GMP deletion - r=cpearce

This commit is contained in:
Edwin Flores 2015-04-20 16:21:35 +12:00
parent b67d865b08
commit a6f18578e9

View File

@ -737,6 +737,11 @@ GeckoMediaPluginServiceParent::RemoveOnGMPThread(const nsAString& aDirectory,
return; return;
} }
// Plugin destruction can modify |mPlugins|. Put them aside for now and
// destroy them once we're done with |mPlugins|.
nsTArray<nsRefPtr<GMPParent>> deadPlugins;
bool inUse = false;
MutexAutoLock lock(mMutex); MutexAutoLock lock(mMutex);
for (size_t i = mPlugins.Length() - 1; i < mPlugins.Length(); i--) { for (size_t i = mPlugins.Length() - 1; i < mPlugins.Length(); i--) {
nsCOMPtr<nsIFile> pluginpath = mPlugins[i]->GetDirectory(); nsCOMPtr<nsIFile> pluginpath = mPlugins[i]->GetDirectory();
@ -749,6 +754,7 @@ GeckoMediaPluginServiceParent::RemoveOnGMPThread(const nsAString& aDirectory,
if (aDeleteFromDisk && gmp->State() != GMPStateNotLoaded) { if (aDeleteFromDisk && gmp->State() != GMPStateNotLoaded) {
// We have to wait for the child process to release its lib handle // We have to wait for the child process to release its lib handle
// before we can delete the GMP. // before we can delete the GMP.
inUse = true;
gmp->MarkForDeletion(); gmp->MarkForDeletion();
if (!mPluginsWaitingForDeletion.Contains(aDirectory)) { if (!mPluginsWaitingForDeletion.Contains(aDirectory)) {
@ -758,13 +764,20 @@ GeckoMediaPluginServiceParent::RemoveOnGMPThread(const nsAString& aDirectory,
if (gmp->State() == GMPStateNotLoaded || !aCanDefer) { if (gmp->State() == GMPStateNotLoaded || !aCanDefer) {
// GMP not in use or shutdown is being forced; can shut it down now. // GMP not in use or shutdown is being forced; can shut it down now.
gmp->AbortAsyncShutdown(); deadPlugins.AppendElement(gmp);
gmp->CloseActive(true);
mPlugins.RemoveElementAt(i); mPlugins.RemoveElementAt(i);
} }
} }
if (aDeleteFromDisk) { {
MutexAutoUnlock unlock(mMutex);
for (auto& gmp : deadPlugins) {
gmp->AbortAsyncShutdown();
gmp->CloseActive(true);
}
}
if (aDeleteFromDisk && !inUse) {
if (NS_SUCCEEDED(directory->Remove(true))) { if (NS_SUCCEEDED(directory->Remove(true))) {
mPluginsWaitingForDeletion.RemoveElement(aDirectory); mPluginsWaitingForDeletion.RemoveElement(aDirectory);
} }