Bug 1035056 part 2 - Force GMPTimers to shutdown when other API objects do, prevent timers from firing after GMPTimerParent is shutdown. r=jesup

This commit is contained in:
Chris Pearce 2014-08-18 09:41:53 +12:00
parent d195f4a49f
commit 9c9e610e07
3 changed files with 54 additions and 3 deletions

View File

@ -205,6 +205,10 @@ GMPParent::CloseActive(bool aDieWhenUnloaded)
mAudioDecoders[i - 1]->Shutdown();
}
for (uint32_t i = mTimers.Length(); i > 0; i--) {
mTimers[i - 1]->Shutdown();
}
// Note: the shutdown of the codecs is async! don't kill
// the plugin-container until they're all safely shut down via
// CloseIfUnused();

View File

@ -8,10 +8,31 @@
#include "mozilla/unused.h"
namespace mozilla {
#ifdef LOG
#undef LOG
#endif
#ifdef PR_LOGGING
extern PRLogModuleInfo* GetGMPLog();
#define LOGD(msg) PR_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
#define LOG(level, msg) PR_LOG(GetGMPLog(), (level), msg)
#else
#define LOGD(msg)
#define LOG(level, msg)
#endif
#ifdef __CLASS__
#undef __CLASS__
#endif
#define __CLASS__ "GMPParent"
namespace gmp {
GMPTimerParent::GMPTimerParent(nsIThread* aGMPThread)
: mGMPThread(aGMPThread)
, mIsOpen(true)
{
}
@ -19,8 +40,14 @@ bool
GMPTimerParent::RecvSetTimer(const uint32_t& aTimerId,
const uint32_t& aTimeoutMs)
{
LOGD(("%s::%s: %p mIsOpen=%d", __CLASS__, __FUNCTION__, this, mIsOpen));
MOZ_ASSERT(mGMPThread == NS_GetCurrentThread());
if (!mIsOpen) {
return true;
}
nsresult rv;
nsAutoPtr<Context> ctx(new Context());
ctx->mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
@ -42,6 +69,17 @@ GMPTimerParent::RecvSetTimer(const uint32_t& aTimerId,
return true;
}
void
GMPTimerParent::Shutdown()
{
LOGD(("%s::%s: %p mIsOpen=%d", __CLASS__, __FUNCTION__, this, mIsOpen));
MOZ_ASSERT(mGMPThread == NS_GetCurrentThread());
mTimers.EnumerateEntries(GMPTimerParent::CancelTimers, nullptr);
mTimers.Clear();
mIsOpen = false;
}
/*static */
PLDHashOperator
GMPTimerParent::CancelTimers(nsPtrHashKey<Context>* aContext, void* aClosure)
@ -55,9 +93,9 @@ GMPTimerParent::CancelTimers(nsPtrHashKey<Context>* aContext, void* aClosure)
void
GMPTimerParent::ActorDestroy(ActorDestroyReason aWhy)
{
MOZ_ASSERT(mGMPThread == NS_GetCurrentThread());
mTimers.EnumerateEntries(GMPTimerParent::CancelTimers, nullptr);
mTimers.Clear();
LOGD(("%s::%s: %p mIsOpen=%d", __CLASS__, __FUNCTION__, this, mIsOpen));
Shutdown();
}
/* static */
@ -75,8 +113,13 @@ GMPTimerParent::GMPTimerExpired(nsITimer *aTimer, void *aClosure)
void
GMPTimerParent::TimerExpired(Context* aContext)
{
LOGD(("%s::%s: %p mIsOpen=%d", __CLASS__, __FUNCTION__, this, mIsOpen));
MOZ_ASSERT(mGMPThread == NS_GetCurrentThread());
if (!mIsOpen) {
return;
}
uint32_t id = aContext->mId;
mTimers.RemoveEntry(aContext);
if (id) {

View File

@ -23,6 +23,8 @@ public:
NS_INLINE_DECL_REFCOUNTING(GMPTimerParent)
GMPTimerParent(nsIThread* aGMPThread);
void Shutdown();
protected:
virtual bool RecvSetTimer(const uint32_t& aTimerId,
const uint32_t& aTimeoutMs) MOZ_OVERRIDE;
@ -53,6 +55,8 @@ private:
nsTHashtable<nsPtrHashKey<Context>> mTimers;
nsCOMPtr<nsIThread> mGMPThread;
bool mIsOpen;
};
} // namespace gmp