diff --git a/netwerk/base/EventTokenBucket.cpp b/netwerk/base/EventTokenBucket.cpp index 9e8edeb61e5..e12624ea2a5 100644 --- a/netwerk/base/EventTokenBucket.cpp +++ b/netwerk/base/EventTokenBucket.cpp @@ -111,25 +111,35 @@ EventTokenBucket::~EventTokenBucket() SOCKET_LOG(("EventTokenBucket::dtor %p events=%d\n", this, mEvents.GetSize())); - if (mTimer && mTimerArmed) - mTimer->Cancel(); - -#ifdef XP_WIN - NormalTimers(); - if (mFineGrainResetTimerArmed) { - mFineGrainResetTimerArmed = false; - mFineGrainResetTimer->Cancel(); - } -#endif + CleanupTimers(); // Complete any queued events to prevent hangs while (mEvents.GetSize()) { - RefPtr cancelable = + RefPtr cancelable = dont_AddRef(static_cast(mEvents.PopFront())); cancelable->Fire(); } } +void +EventTokenBucket::CleanupTimers() +{ + if (mTimer && mTimerArmed) { + mTimer->Cancel(); + } + mTimer = nullptr; + mTimerArmed = false; + +#ifdef XP_WIN + NormalTimers(); + if (mFineGrainResetTimer && mFineGrainResetTimerArmed) { + mFineGrainResetTimer->Cancel(); + } + mFineGrainResetTimer = nullptr; + mFineGrainResetTimerArmed = false; +#endif +} + void EventTokenBucket::SetRate(uint32_t eventsPerSecond, uint32_t burstSize) @@ -213,9 +223,13 @@ EventTokenBucket::Stop() MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); SOCKET_LOG(("EventTokenBucket::Stop %p armed=%d\n", this, mTimerArmed)); mStopped = true; - if (mTimerArmed) { - mTimer->Cancel(); - mTimerArmed = false; + CleanupTimers(); + + // Complete any queued events to prevent hangs + while (mEvents.GetSize()) { + RefPtr cancelable = + dont_AddRef(static_cast(mEvents.PopFront())); + cancelable->Fire(); } } diff --git a/netwerk/base/EventTokenBucket.h b/netwerk/base/EventTokenBucket.h index ff14abe65a4..b187ca7b061 100644 --- a/netwerk/base/EventTokenBucket.h +++ b/netwerk/base/EventTokenBucket.h @@ -93,6 +93,7 @@ public: private: virtual ~EventTokenBucket(); + void CleanupTimers(); friend class RunNotifyEvent; friend class SetTimerEvent; diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index e418bc7ad67..1830dec502a 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -385,9 +385,11 @@ nsHttpHandler::Init() void nsHttpHandler::MakeNewRequestTokenBucket() { - if (!mConnMgr) + LOG(("nsHttpHandler::MakeNewRequestTokenBucket this=%p child=%d\n", + this, IsNeckoChild())); + if (!mConnMgr || IsNeckoChild()) { return; - + } RefPtr tokenBucket = new EventTokenBucket(RequestTokenBucketHz(), RequestTokenBucketBurst()); mConnMgr->UpdateRequestTokenBucket(tokenBucket); diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h index 010a8c3f6cd..6aae0f39de8 100644 --- a/netwerk/protocol/http/nsHttpHandler.h +++ b/netwerk/protocol/http/nsHttpHandler.h @@ -568,8 +568,9 @@ public: nsICancelable **cancel) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); - if (!mRequestTokenBucket) - return NS_ERROR_UNEXPECTED; + if (!mRequestTokenBucket) { + return NS_ERROR_NOT_AVAILABLE; + } return mRequestTokenBucket->SubmitEvent(event, cancel); }