Backout 303027a0da95 (bug 1013571) due to persistent oranges (bug 1032011, bug 1032605, bug 1032783)

This commit is contained in:
Ben Kelly 2014-07-04 00:31:59 -04:00
parent 736358712e
commit d0ce16a691
4 changed files with 9 additions and 246 deletions

View File

@ -21,7 +21,6 @@
#include "nsPIDOMWindow.h" #include "nsPIDOMWindow.h"
#include <algorithm> #include <algorithm>
#include "BackgroundChild.h"
#include "GeckoProfiler.h" #include "GeckoProfiler.h"
#include "js/OldDebugAPI.h" #include "js/OldDebugAPI.h"
#include "jsfriendapi.h" #include "jsfriendapi.h"
@ -41,7 +40,6 @@
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsCycleCollector.h" #include "nsCycleCollector.h"
#include "nsDOMJSUtils.h" #include "nsDOMJSUtils.h"
#include "nsIIPCBackgroundChildCreateCallback.h"
#include "nsISupportsImpl.h" #include "nsISupportsImpl.h"
#include "nsLayoutStatics.h" #include "nsLayoutStatics.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
@ -66,12 +64,6 @@
#include "WorkerPrivate.h" #include "WorkerPrivate.h"
#include "WorkerRunnable.h" #include "WorkerRunnable.h"
#ifdef ENABLE_TESTS
#include "BackgroundChildImpl.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "prrng.h"
#endif
using namespace mozilla; using namespace mozilla;
using namespace mozilla::dom; using namespace mozilla::dom;
@ -169,10 +161,6 @@ RuntimeService* gRuntimeService = nullptr;
// Only non-null during the call to Init. // Only non-null during the call to Init.
RuntimeService* gRuntimeServiceDuringInit = nullptr; RuntimeService* gRuntimeServiceDuringInit = nullptr;
#ifdef ENABLE_TESTS
bool gTestPBackground = false;
#endif // ENABLE_TESTS
enum { enum {
ID_Worker = 0, ID_Worker = 0,
ID_ChromeWorker, ID_ChromeWorker,
@ -911,37 +899,6 @@ private:
WorkerPrivate* mWorkerPrivate; WorkerPrivate* mWorkerPrivate;
}; };
class WorkerBackgroundChildCallback MOZ_FINAL :
public nsIIPCBackgroundChildCreateCallback
{
bool* mDone;
public:
WorkerBackgroundChildCallback(bool* aDone)
: mDone(aDone)
{
MOZ_ASSERT(mDone);
}
NS_DECL_ISUPPORTS
private:
~WorkerBackgroundChildCallback()
{ }
virtual void
ActorCreated(PBackgroundChild* aActor) MOZ_OVERRIDE
{
*mDone = true;
}
virtual void
ActorFailed() MOZ_OVERRIDE
{
*mDone = true;
}
};
class WorkerThreadPrimaryRunnable MOZ_FINAL : public nsRunnable class WorkerThreadPrimaryRunnable MOZ_FINAL : public nsRunnable
{ {
WorkerPrivate* mWorkerPrivate; WorkerPrivate* mWorkerPrivate;
@ -984,9 +941,6 @@ private:
~WorkerThreadPrimaryRunnable() ~WorkerThreadPrimaryRunnable()
{ } { }
nsresult
SynchronouslyCreatePBackground();
NS_DECL_NSIRUNNABLE NS_DECL_NSIRUNNABLE
}; };
@ -1086,28 +1040,6 @@ public:
} }
#endif #endif
#ifdef ENABLE_TESTS
void
TestPBackground()
{
using namespace mozilla::ipc;
if (gTestPBackground) {
// Randomize value to validate workers are not cross-posting messages.
uint32_t testValue;
PRSize randomSize = PR_GetRandomNoise(&testValue, sizeof(testValue));
MOZ_RELEASE_ASSERT(randomSize == sizeof(testValue));
nsCString testStr;
testStr.AppendInt(testValue);
testStr.AppendInt(reinterpret_cast<int64_t>(PR_GetCurrentThread()));
PBackgroundChild* existingBackgroundChild =
BackgroundChild::GetForCurrentThread();
MOZ_RELEASE_ASSERT(existingBackgroundChild);
bool ok = existingBackgroundChild->SendPBackgroundTestConstructor(testStr);
MOZ_RELEASE_ASSERT(ok);
}
}
#endif // #ENABLE_TESTS
private: private:
WorkerThread() WorkerThread()
: nsThread(nsThread::NOT_MAIN_THREAD, WORKER_STACK_SIZE), : nsThread(nsThread::NOT_MAIN_THREAD, WORKER_STACK_SIZE),
@ -1311,10 +1243,6 @@ RuntimeService::GetOrCreateService()
return nullptr; return nullptr;
} }
#ifdef ENABLE_TESTS
gTestPBackground = mozilla::Preferences::GetBool("pbackground.testing", false);
#endif // ENABLE_TESTS
// The observer service now owns us until shutdown. // The observer service now owns us until shutdown.
gRuntimeService = service; gRuntimeService = service;
} }
@ -1604,6 +1532,10 @@ RuntimeService::ScheduleWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
return false; return false;
} }
#ifdef DEBUG
thread->SetAcceptingNonWorkerRunnables(false);
#endif
return true; return true;
} }
@ -2592,20 +2524,8 @@ RuntimeService::WorkerThread::Observer::OnProcessNextEvent(
bool aMayWait, bool aMayWait,
uint32_t aRecursionDepth) uint32_t aRecursionDepth)
{ {
using mozilla::ipc::BackgroundChild;
mWorkerPrivate->AssertIsOnWorkerThread(); mWorkerPrivate->AssertIsOnWorkerThread();
MOZ_ASSERT(!aMayWait);
// If the PBackground child is not created yet, then we must permit
// blocking event processing to support SynchronouslyCreatePBackground().
// If this occurs then we are spinning on the event queue at the start of
// PrimaryWorkerRunnable::Run() and don't want to process the event in
// mWorkerPrivate yet.
if (aMayWait) {
MOZ_ASSERT(aRecursionDepth == 2);
MOZ_ASSERT(!BackgroundChild::GetForCurrentThread());
return NS_OK;
}
mWorkerPrivate->OnProcessNextEvent(aRecursionDepth); mWorkerPrivate->OnProcessNextEvent(aRecursionDepth);
return NS_OK; return NS_OK;
@ -2649,15 +2569,11 @@ LogViolationDetailsRunnable::Run()
return NS_OK; return NS_OK;
} }
NS_IMPL_ISUPPORTS(WorkerBackgroundChildCallback, nsIIPCBackgroundChildCreateCallback)
NS_IMPL_ISUPPORTS_INHERITED0(WorkerThreadPrimaryRunnable, nsRunnable) NS_IMPL_ISUPPORTS_INHERITED0(WorkerThreadPrimaryRunnable, nsRunnable)
NS_IMETHODIMP NS_IMETHODIMP
WorkerThreadPrimaryRunnable::Run() WorkerThreadPrimaryRunnable::Run()
{ {
using mozilla::ipc::BackgroundChild;
#ifdef MOZ_NUWA_PROCESS #ifdef MOZ_NUWA_PROCESS
if (IsNuwaProcess()) { if (IsNuwaProcess()) {
NS_ASSERTION(NuwaMarkCurrentThread != nullptr, NS_ASSERTION(NuwaMarkCurrentThread != nullptr,
@ -2676,19 +2592,6 @@ WorkerThreadPrimaryRunnable::Run()
profiler_register_thread(threadName.get(), &stackBaseGuess); profiler_register_thread(threadName.get(), &stackBaseGuess);
// Note: SynchronouslyCreatePBackground() must be called prior to
// mThread->SetWorker() in order to avoid accidentally consuming
// worker messages here.
nsresult rv = SynchronouslyCreatePBackground();
if (NS_WARN_IF(NS_FAILED(rv))) {
// XXX need to fire an error at parent.
return rv;
}
#ifdef ENABLE_TESTS
mThread->TestPBackground();
#endif
mThread->SetWorker(mWorkerPrivate); mThread->SetWorker(mWorkerPrivate);
mWorkerPrivate->AssertIsOnWorkerThread(); mWorkerPrivate->AssertIsOnWorkerThread();
@ -2722,12 +2625,6 @@ WorkerThreadPrimaryRunnable::Run()
JS_ReportPendingException(cx); JS_ReportPendingException(cx);
} }
#ifdef ENABLE_TESTS
mThread->TestPBackground();
#endif
BackgroundChild::CloseForCurrentThread();
#ifdef MOZ_ENABLE_PROFILER_SPS #ifdef MOZ_ENABLE_PROFILER_SPS
if (stack) { if (stack) {
stack->sampleRuntime(nullptr); stack->sampleRuntime(nullptr);
@ -2766,38 +2663,6 @@ WorkerThreadPrimaryRunnable::Run()
return NS_OK; return NS_OK;
} }
nsresult
WorkerThreadPrimaryRunnable::SynchronouslyCreatePBackground()
{
using mozilla::ipc::BackgroundChild;
MOZ_ASSERT(!BackgroundChild::GetForCurrentThread());
bool done = false;
nsCOMPtr<nsIIPCBackgroundChildCreateCallback> callback =
new WorkerBackgroundChildCallback(&done);
if (NS_WARN_IF(!BackgroundChild::GetOrCreateForCurrentThread(callback))) {
return NS_ERROR_FAILURE;
}
while (!done) {
if (NS_WARN_IF(!NS_ProcessNextEvent(mThread, true /* aMayWay */))) {
return NS_ERROR_FAILURE;
}
}
if (NS_WARN_IF(!BackgroundChild::GetForCurrentThread())) {
return NS_ERROR_FAILURE;
}
#ifdef DEBUG
mThread->SetAcceptingNonWorkerRunnables(false);
#endif
return NS_OK;
}
NS_IMPL_ISUPPORTS_INHERITED0(WorkerThreadPrimaryRunnable::FinishedRunnable, NS_IMPL_ISUPPORTS_INHERITED0(WorkerThreadPrimaryRunnable::FinishedRunnable,
nsRunnable) nsRunnable)

View File

@ -37,11 +37,6 @@ class PBackgroundChild;
// (assuming success) GetForCurrentThread() will return the same actor every // (assuming success) GetForCurrentThread() will return the same actor every
// time. // time.
// //
// CloseForCurrentThread() will close the current PBackground actor. Subsequent
// calls to GetForCurrentThread will return null. CloseForCurrentThread() may
// only be called exactly once per thread. Currently it is illegal to call this
// before the PBackground actor has been created.
//
// The PBackgroundChild actor and all its sub-protocol actors will be // The PBackgroundChild actor and all its sub-protocol actors will be
// automatically destroyed when its designated thread completes. // automatically destroyed when its designated thread completes.
class BackgroundChild MOZ_FINAL class BackgroundChild MOZ_FINAL
@ -61,10 +56,6 @@ public:
static bool static bool
GetOrCreateForCurrentThread(nsIIPCBackgroundChildCreateCallback* aCallback); GetOrCreateForCurrentThread(nsIIPCBackgroundChildCreateCallback* aCallback);
// See above.
static void
CloseForCurrentThread();
private: private:
// Only called by ContentChild or ContentParent. // Only called by ContentChild or ContentParent.
static void static void

View File

@ -350,8 +350,6 @@ class ChildImpl MOZ_FINAL : public BackgroundChildImpl
nsIThread* mBoundThread; nsIThread* mBoundThread;
#endif #endif
DebugOnly<bool> mActorDestroyed;
public: public:
static bool static bool
OpenProtocolOnMainThread(nsIEventTarget* aEventTarget); OpenProtocolOnMainThread(nsIEventTarget* aEventTarget);
@ -374,15 +372,8 @@ public:
THREADSAFETY_ASSERT(current); THREADSAFETY_ASSERT(current);
} }
void
AssertActorDestroyed()
{
MOZ_ASSERT(mActorDestroyed, "ChildImpl::ActorDestroy not called in time");
}
ChildImpl() ChildImpl()
: mBoundThread(nullptr) : mBoundThread(nullptr)
, mActorDestroyed(false)
{ {
AssertIsOnMainThread(); AssertIsOnMainThread();
} }
@ -406,10 +397,6 @@ private:
static bool static bool
GetOrCreateForCurrentThread(nsIIPCBackgroundChildCreateCallback* aCallback); GetOrCreateForCurrentThread(nsIIPCBackgroundChildCreateCallback* aCallback);
// Forwarded from BackgroundChild.
static void
CloseForCurrentThread();
// Forwarded from BackgroundChildImpl. // Forwarded from BackgroundChildImpl.
static BackgroundChildImpl::ThreadLocal* static BackgroundChildImpl::ThreadLocal*
GetThreadLocalForCurrentThread(); GetThreadLocalForCurrentThread();
@ -422,17 +409,6 @@ private:
if (threadLocalInfo) { if (threadLocalInfo) {
if (threadLocalInfo->mActor) { if (threadLocalInfo->mActor) {
threadLocalInfo->mActor->Close(); threadLocalInfo->mActor->Close();
threadLocalInfo->mActor->AssertActorDestroyed();
// Since the actor is created on the main thread it must only
// be released on the main thread as well.
if (!NS_IsMainThread()) {
ChildImpl* actor;
threadLocalInfo->mActor.forget(&actor);
nsCOMPtr<nsIRunnable> releaser =
NS_NewNonOwningRunnableMethod(actor, &ChildImpl::Release);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(releaser)));
}
} }
delete threadLocalInfo; delete threadLocalInfo;
} }
@ -443,9 +419,7 @@ private:
// This class is reference counted. // This class is reference counted.
~ChildImpl() ~ChildImpl()
{ { }
AssertActorDestroyed();
}
void void
SetBoundThread() SetBoundThread()
@ -861,13 +835,6 @@ BackgroundChild::GetOrCreateForCurrentThread(
return ChildImpl::GetOrCreateForCurrentThread(aCallback); return ChildImpl::GetOrCreateForCurrentThread(aCallback);
} }
// static
void
BackgroundChild::CloseForCurrentThread()
{
ChildImpl::CloseForCurrentThread();
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// BackgroundChildImpl Public Methods // BackgroundChildImpl Public Methods
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -1611,11 +1578,7 @@ ChildImpl::GetForCurrentThread()
auto threadLocalInfo = auto threadLocalInfo =
static_cast<ThreadLocalInfo*>(PR_GetThreadPrivate(sThreadLocalIndex)); static_cast<ThreadLocalInfo*>(PR_GetThreadPrivate(sThreadLocalIndex));
if (!threadLocalInfo) { return threadLocalInfo ? threadLocalInfo->mActor : nullptr;
return nullptr;
}
return threadLocalInfo->mActor;
} }
// static // static
@ -1679,31 +1642,6 @@ ChildImpl::GetOrCreateForCurrentThread(
return true; return true;
} }
// static
void
ChildImpl::CloseForCurrentThread()
{
MOZ_ASSERT(sThreadLocalIndex != kBadThreadLocalIndex,
"BackgroundChild::Startup() was never called!");
auto threadLocalInfo =
static_cast<ThreadLocalInfo*>(PR_GetThreadPrivate(sThreadLocalIndex));
// If we don't have a thread local we are in one of these conditions:
// 1) Startup has not completed and we are racing
// 2) We were called again after a previous close or shutdown
// For now, these should not happen, so crash. We can add extra complexity
// in the future if it turns out we need to support these cases.
if (!threadLocalInfo) {
MOZ_CRASH("Attempting to close a non-existent PBackground actor!");
}
if (threadLocalInfo->mActor) {
threadLocalInfo->mActor->FlushPendingInterruptQueue();
}
DebugOnly<PRStatus> status = PR_SetThreadPrivate(sThreadLocalIndex, nullptr);
MOZ_ASSERT(status == PR_SUCCESS);
}
// static // static
BackgroundChildImpl::ThreadLocal* BackgroundChildImpl::ThreadLocal*
ChildImpl::GetThreadLocalForCurrentThread() ChildImpl::GetThreadLocalForCurrentThread()
@ -2008,7 +1946,6 @@ ChildImpl::ActorDestroy(ActorDestroyReason aWhy)
{ {
AssertIsOnBoundThread(); AssertIsOnBoundThread();
mActorDestroyed = true;
BackgroundChildImpl::ActorDestroy(aWhy); BackgroundChildImpl::ActorDestroy(aWhy);
} }

View File

@ -7,13 +7,11 @@
#include "nsIRunnable.h" #include "nsIRunnable.h"
#include "nsIThread.h" #include "nsIThread.h"
#include "nsITimer.h" #include "nsITimer.h"
#include "nsICancelableRunnable.h"
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/scoped_nsautorelease_pool.h" #include "base/scoped_nsautorelease_pool.h"
#include "mozilla/Assertions.h" #include "mozilla/Assertions.h"
#include "mozilla/AutoRestore.h"
#include "mozilla/DebugOnly.h" #include "mozilla/DebugOnly.h"
#include "nsComponentManagerUtils.h" #include "nsComponentManagerUtils.h"
#include "nsDebug.h" #include "nsDebug.h"
@ -42,14 +40,12 @@ static mozilla::DebugOnly<MessagePump::Delegate*> gFirstDelegate;
namespace mozilla { namespace mozilla {
namespace ipc { namespace ipc {
class DoWorkRunnable MOZ_FINAL : public nsICancelableRunnable, class DoWorkRunnable MOZ_FINAL : public nsIRunnable,
public nsITimerCallback public nsITimerCallback
{ {
public: public:
DoWorkRunnable(MessagePump* aPump) DoWorkRunnable(MessagePump* aPump)
: mPump(aPump) : mPump(aPump)
, mCanceled(false)
, mCallingRunWhileCanceled(false)
{ {
MOZ_ASSERT(aPump); MOZ_ASSERT(aPump);
} }
@ -57,15 +53,12 @@ public:
NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIRUNNABLE NS_DECL_NSIRUNNABLE
NS_DECL_NSITIMERCALLBACK NS_DECL_NSITIMERCALLBACK
NS_DECL_NSICANCELABLERUNNABLE
private: private:
~DoWorkRunnable() ~DoWorkRunnable()
{ } { }
MessagePump* mPump; MessagePump* mPump;
bool mCanceled;
bool mCallingRunWhileCanceled;
}; };
} /* namespace ipc */ } /* namespace ipc */
@ -218,17 +211,11 @@ MessagePump::DoDelayedWork(base::MessagePump::Delegate* aDelegate)
} }
} }
NS_IMPL_ISUPPORTS(DoWorkRunnable, nsIRunnable, nsITimerCallback, NS_IMPL_ISUPPORTS(DoWorkRunnable, nsIRunnable, nsITimerCallback)
nsICancelableRunnable)
NS_IMETHODIMP NS_IMETHODIMP
DoWorkRunnable::Run() DoWorkRunnable::Run()
{ {
MOZ_ASSERT(!mCanceled || mCallingRunWhileCanceled);
if (mCanceled && !mCallingRunWhileCanceled) {
return NS_OK;
}
MessageLoop* loop = MessageLoop::current(); MessageLoop* loop = MessageLoop::current();
MOZ_ASSERT(loop); MOZ_ASSERT(loop);
@ -255,23 +242,6 @@ DoWorkRunnable::Notify(nsITimer* aTimer)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
DoWorkRunnable::Cancel()
{
MOZ_ASSERT(!mCanceled);
MOZ_ASSERT(!mCallingRunWhileCanceled);
// Workers require cancelable runnables, but we can't really cancel cleanly
// here. If we don't process all of these then we will leave something
// unprocessed in the chromium queue. Therefore, eagerly complete our work
// instead by immediately calling Run().
mCanceled = true;
mozilla::AutoRestore<bool> guard(mCallingRunWhileCanceled);
mCallingRunWhileCanceled = true;
Run();
return NS_OK;
}
void void
MessagePumpForChildProcess::Run(base::MessagePump::Delegate* aDelegate) MessagePumpForChildProcess::Run(base::MessagePump::Delegate* aDelegate)
{ {