Bug 956218 - '(PBackground) Add a mechanism for communicating with

a non-main I/O thread via thread and process links'. r=mrbkap+khuey+bsmedberg.
This commit is contained in:
Ben Turner 2013-11-26 23:59:41 -08:00
parent 0282e9aebb
commit 4891b5f251
20 changed files with 2560 additions and 6 deletions

View File

@ -23,6 +23,7 @@
#include "mozilla/dom/PCrashReporterChild.h"
#include "mozilla/dom/DOMStorageIPC.h"
#include "mozilla/hal_sandbox/PHalChild.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/GeckoChildProcessHost.h"
#include "mozilla/ipc/TestShellChild.h"
#include "mozilla/layers/CompositorChild.h"
@ -43,6 +44,7 @@
#include "mozilla/unused.h"
#include "nsIConsoleListener.h"
#include "nsIIPCBackgroundChildCreateCallback.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIMemoryReporter.h"
#include "nsIMemoryInfoDumper.h"
@ -310,6 +312,34 @@ SystemMessageHandledObserver::Observe(nsISupports* aSubject,
NS_IMPL_ISUPPORTS1(SystemMessageHandledObserver, nsIObserver)
class BackgroundChildPrimer MOZ_FINAL :
public nsIIPCBackgroundChildCreateCallback
{
public:
BackgroundChildPrimer()
{ }
NS_DECL_ISUPPORTS
private:
~BackgroundChildPrimer()
{ }
virtual void
ActorCreated(PBackgroundChild* aActor) MOZ_OVERRIDE
{
MOZ_ASSERT(aActor, "Failed to create a PBackgroundChild actor!");
}
virtual void
ActorFailed() MOZ_OVERRIDE
{
MOZ_CRASH("Failed to create a PBackgroundChild actor!");
}
};
NS_IMPL_ISUPPORTS1(BackgroundChildPrimer, nsIIPCBackgroundChildCreateCallback)
ContentChild* ContentChild::sSingleton;
// Performs initialization that is not fork-safe, i.e. that must be done after
@ -451,6 +481,16 @@ ContentChild::AppendProcessId(nsACString& aName)
void
ContentChild::InitXPCOM()
{
// Do this as early as possible to get the parent process to initialize the
// background thread since we'll likely need database information very soon.
BackgroundChild::Startup();
nsCOMPtr<nsIIPCBackgroundChildCreateCallback> callback =
new BackgroundChildPrimer();
if (!BackgroundChild::GetOrCreateForCurrentThread(callback)) {
MOZ_CRASH("Failed to create PBackgroundChild!");
}
nsCOMPtr<nsIConsoleService> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
if (!svc) {
NS_WARNING("Couldn't acquire console service");
@ -606,6 +646,13 @@ ContentChild::AllocPImageBridgeChild(mozilla::ipc::Transport* aTransport,
return ImageBridgeChild::StartUpInChildProcess(aTransport, aOtherProcess);
}
PBackgroundChild*
ContentChild::AllocPBackgroundChild(Transport* aTransport,
ProcessId aOtherProcess)
{
return BackgroundChild::Alloc(aTransport, aOtherProcess);
}
bool
ContentChild::RecvSetProcessPrivileges(const ChildPrivileges& aPrivs)
{
@ -1686,6 +1733,20 @@ ContentChild::RecvNuwaFork()
}
sNuwaForking = true;
// We want to ensure that the PBackground actor gets cloned in the Nuwa
// process before we freeze. Also, we have to do this to avoid deadlock.
// Protocols that are "opened" (e.g. PBackground, PCompositor) block the
// main thread to wait for the IPC thread during the open operation.
// NuwaSpawnWait() blocks the IPC thread to wait for the main thread when
// the Nuwa process is forked. Unless we ensure that the two cannot happen
// at the same time then we risk deadlock. Spinning the event loop here
// guarantees the ordering is safe for PBackground.
while (!BackgroundChild::GetForCurrentThread()) {
if (NS_WARN_IF(NS_FAILED(NS_ProcessNextEvent()))) {
return false;
}
}
MessageLoop* ioloop = XRE_GetIOMessageLoop();
ioloop->PostTask(FROM_HERE, NewRunnableFunction(RunNuwaFork));
return true;

View File

@ -88,6 +88,10 @@ public:
virtual bool RecvSetProcessPrivileges(const ChildPrivileges& aPrivs) MOZ_OVERRIDE;
PBackgroundChild*
AllocPBackgroundChild(Transport* aTransport, ProcessId aOtherProcess)
MOZ_OVERRIDE;
virtual PBrowserChild* AllocPBrowserChild(const IPCTabContext &aContext,
const uint32_t &chromeFlags);
virtual bool DeallocPBrowserChild(PBrowserChild*);

View File

@ -39,6 +39,8 @@
#include "mozilla/dom/telephony/TelephonyParent.h"
#include "SmsParent.h"
#include "mozilla/hal_sandbox/PHalParent.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/ipc/TestShellParent.h"
#include "mozilla/ipc/InputStreamUtils.h"
#include "mozilla/layers/CompositorParent.h"
@ -138,6 +140,11 @@ using namespace mozilla::system;
#include "mozilla/dom/SpeechSynthesisParent.h"
#endif
#ifdef ENABLE_TESTS
#include "mozilla/ipc/PBackgroundChild.h"
#include "nsIIPCBackgroundChildCreateCallback.h"
#endif
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
static const char* sClipboardTextFlavors[] = { kUnicodeMime };
@ -155,6 +162,127 @@ using namespace mozilla::layers;
using namespace mozilla::net;
using namespace mozilla::jsipc;
#ifdef ENABLE_TESTS
class BackgroundTester MOZ_FINAL : public nsIIPCBackgroundChildCreateCallback,
public nsIObserver
{
static uint32_t sCallbackCount;
private:
~BackgroundTester()
{ }
virtual void
ActorCreated(PBackgroundChild* aActor) MOZ_OVERRIDE
{
MOZ_RELEASE_ASSERT(aActor,
"Failed to create a PBackgroundChild actor!");
NS_NAMED_LITERAL_CSTRING(testStr, "0123456789");
PBackgroundTestChild* testActor =
aActor->SendPBackgroundTestConstructor(testStr);
MOZ_RELEASE_ASSERT(testActor);
if (!sCallbackCount) {
PBackgroundChild* existingBackgroundChild =
BackgroundChild::GetForCurrentThread();
MOZ_RELEASE_ASSERT(existingBackgroundChild);
MOZ_RELEASE_ASSERT(existingBackgroundChild == aActor);
bool ok =
existingBackgroundChild->
SendPBackgroundTestConstructor(testStr);
MOZ_RELEASE_ASSERT(ok);
// Callback 3.
ok = BackgroundChild::GetOrCreateForCurrentThread(this);
MOZ_RELEASE_ASSERT(ok);
}
sCallbackCount++;
}
virtual void
ActorFailed() MOZ_OVERRIDE
{
MOZ_CRASH("Failed to create a PBackgroundChild actor!");
}
NS_IMETHOD
Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData)
MOZ_OVERRIDE
{
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
MOZ_RELEASE_ASSERT(observerService);
nsresult rv = observerService->RemoveObserver(this, aTopic);
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
if (!strcmp(aTopic, "profile-after-change")) {
if (mozilla::Preferences::GetBool("pbackground.testing", false)) {
rv = observerService->AddObserver(this, "xpcom-shutdown",
false);
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
// Callback 1.
bool ok = BackgroundChild::GetOrCreateForCurrentThread(this);
MOZ_RELEASE_ASSERT(ok);
// Callback 2.
ok = BackgroundChild::GetOrCreateForCurrentThread(this);
MOZ_RELEASE_ASSERT(ok);
}
return NS_OK;
}
if (!strcmp(aTopic, "xpcom-shutdown")) {
MOZ_RELEASE_ASSERT(sCallbackCount == 3);
return NS_OK;
}
MOZ_CRASH("Unknown observer topic!");
}
public:
NS_DECL_ISUPPORTS
};
uint32_t BackgroundTester::sCallbackCount = 0;
NS_IMPL_ISUPPORTS2(BackgroundTester, nsIIPCBackgroundChildCreateCallback,
nsIObserver)
#endif // ENABLE_TESTS
void
MaybeTestPBackground()
{
#ifdef ENABLE_TESTS
// This test relies on running the event loop and XPCShell does not always
// do so. Bail out here if we detect that we're running in XPCShell.
if (PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR")) {
return;
}
// This is called too early at startup to test preferences directly. We have
// to install an observer to be notified when preferences are available.
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
MOZ_RELEASE_ASSERT(observerService);
nsCOMPtr<nsIObserver> observer = new BackgroundTester();
nsresult rv = observerService->AddObserver(observer, "profile-after-change",
false);
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
#endif
}
namespace mozilla {
namespace dom {
@ -360,10 +488,16 @@ ContentParent::StartUp()
// Note: This reporter measures all ContentParents.
RegisterStrongMemoryReporter(new ContentParentsMemoryReporter());
BackgroundChild::Startup();
sCanLaunchSubprocesses = true;
// Try to preallocate a process that we can transform into an app later.
PreallocatedProcessManager::AllocateAfterDelay();
// Test the PBackground infrastructure on ENABLE_TESTS builds when a special
// testing preference is set.
MaybeTestPBackground();
}
/*static*/ void
@ -1973,6 +2107,13 @@ ContentParent::AllocPImageBridgeParent(mozilla::ipc::Transport* aTransport,
return ImageBridgeParent::Create(aTransport, aOtherProcess);
}
PBackgroundParent*
ContentParent::AllocPBackgroundParent(Transport* aTransport,
ProcessId aOtherProcess)
{
return BackgroundParent::Alloc(this, aTransport, aOtherProcess);
}
bool
ContentParent::RecvGetProcessAttributes(uint64_t* aId,
bool* aIsForApp, bool* aIsForBrowser)

View File

@ -327,6 +327,10 @@ private:
AllocPImageBridgeParent(mozilla::ipc::Transport* aTransport,
base::ProcessId aOtherProcess) MOZ_OVERRIDE;
PBackgroundParent*
AllocPBackgroundParent(Transport* aTransport, ProcessId aOtherProcess)
MOZ_OVERRIDE;
virtual bool RecvGetProcessAttributes(uint64_t* aId,
bool* aIsForApp,
bool* aIsForBrowser) MOZ_OVERRIDE;

View File

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PAsmJSCacheEntry;
include protocol PBackground;
include protocol PBlob;
include protocol PBluetooth;
include protocol PBrowser;
@ -199,6 +200,7 @@ intr protocol PContent
{
parent opens PCompositor;
parent opens PImageBridge;
child opens PBackground;
manages PAsmJSCacheEntry;
manages PBlob;

View File

@ -124,4 +124,8 @@ for var in ('MOZ_PERMISSIONS', 'MOZ_CHILD_PERMISSIONS'):
if CONFIG[var]:
DEFINES[var] = True
if CONFIG['ENABLE_TESTS']:
DEFINES['ENABLE_TESTS'] = 1
JAR_MANIFESTS += ['jar.mn']

View File

@ -0,0 +1,72 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_backgroundchild_h__
#define mozilla_ipc_backgroundchild_h__
#include "base/process.h"
#include "mozilla/Attributes.h"
#include "mozilla/ipc/Transport.h"
class nsIIPCBackgroundChildCreateCallback;
namespace mozilla {
namespace dom {
class ContentChild;
class ContentParent;
} // namespace dom
namespace ipc {
class PBackgroundChild;
// This class allows access to the PBackground protocol. PBackground allows
// communication between any thread (in the parent or a child process) and a
// single background thread in the parent process. Each PBackgroundChild
// instance is tied to the thread on which it is created and must not be shared
// across threads. Each PBackgroundChild is unique and valid as long as its
// designated thread lives.
//
// Creation of PBackground is asynchronous. GetForCurrentThread() will return
// null until the sequence is complete. GetOrCreateForCurrentThread() will start
// the creation sequence and will call back via the
// nsIIPCBackgroundChildCreateCallback interface when completed. Thereafter
// (assuming success) GetForCurrentThread() will return the same actor every
// time.
//
// The PBackgroundChild actor and all its sub-protocol actors will be
// automatically destroyed when its designated thread completes.
class BackgroundChild MOZ_FINAL
{
friend class mozilla::dom::ContentChild;
friend class mozilla::dom::ContentParent;
typedef base::ProcessId ProcessId;
typedef mozilla::ipc::Transport Transport;
public:
// See above.
static PBackgroundChild*
GetForCurrentThread();
// See above.
static bool
GetOrCreateForCurrentThread(nsIIPCBackgroundChildCreateCallback* aCallback);
private:
// Only called by ContentChild or ContentParent.
static void
Startup();
// Only called by ContentChild.
static PBackgroundChild*
Alloc(Transport* aTransport, ProcessId aOtherProcess);
};
} // namespace ipc
} // namespace mozilla
#endif // mozilla_ipc_backgroundchild_h__

View File

@ -0,0 +1,81 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BackgroundChildImpl.h"
#include "mozilla/ipc/PBackgroundTestChild.h"
#include "nsTraceRefcnt.h"
namespace {
class TestChild MOZ_FINAL : public mozilla::ipc::PBackgroundTestChild
{
friend class mozilla::ipc::BackgroundChildImpl;
nsCString mTestArg;
TestChild(const nsCString& aTestArg)
: mTestArg(aTestArg)
{
MOZ_COUNT_CTOR(mozilla::ipc::BackgroundTestChild);
}
~TestChild()
{
MOZ_COUNT_DTOR(mozilla::ipc::BackgroundTestChild);
}
virtual bool
Recv__delete__(const nsCString& aTestArg) MOZ_OVERRIDE;
};
} // anonymous namespace
namespace mozilla {
namespace ipc {
BackgroundChildImpl::BackgroundChildImpl()
{
// May happen on any thread!
MOZ_COUNT_CTOR(mozilla::ipc::BackgroundChildImpl);
}
BackgroundChildImpl::~BackgroundChildImpl()
{
// May happen on any thread!
MOZ_COUNT_DTOR(mozilla::ipc::BackgroundChildImpl);
}
void
BackgroundChildImpl::ActorDestroy(ActorDestroyReason aWhy)
{
// May happen on any thread!
}
PBackgroundTestChild*
BackgroundChildImpl::AllocPBackgroundTestChild(const nsCString& aTestArg)
{
return new TestChild(aTestArg);
}
bool
BackgroundChildImpl::DeallocPBackgroundTestChild(PBackgroundTestChild* aActor)
{
MOZ_ASSERT(aActor);
delete static_cast<TestChild*>(aActor);
return true;
}
} // namespace ipc
} // namespace mozilla
bool
TestChild::Recv__delete__(const nsCString& aTestArg)
{
MOZ_RELEASE_ASSERT(aTestArg == mTestArg,
"BackgroundTest message was corrupted!");
return true;
}

View File

@ -0,0 +1,35 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_backgroundchildimpl_h__
#define mozilla_ipc_backgroundchildimpl_h__
#include "mozilla/Attributes.h"
#include "mozilla/ipc/PBackgroundChild.h"
namespace mozilla {
namespace ipc {
// Instances of this class should never be created directly. This class is meant
// to be inherited in BackgroundImpl.
class BackgroundChildImpl : public PBackgroundChild
{
protected:
BackgroundChildImpl();
virtual ~BackgroundChildImpl();
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual PBackgroundTestChild*
AllocPBackgroundTestChild(const nsCString& aTestArg) MOZ_OVERRIDE;
virtual bool
DeallocPBackgroundTestChild(PBackgroundTestChild* aActor) MOZ_OVERRIDE;
};
} // namespace ipc
} // namespace mozilla
#endif // mozilla_ipc_backgroundchildimpl_h__

1800
ipc/glue/BackgroundImpl.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,62 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_backgroundparent_h__
#define mozilla_ipc_backgroundparent_h__
#include "base/process.h"
#include "mozilla/Attributes.h"
#include "mozilla/ipc/Transport.h"
namespace mozilla {
namespace dom {
class ContentParent;
} // namespace dom
namespace ipc {
class PBackgroundParent;
// This class is not designed for public consumption. It must only be used by
// ContentParent.
class BackgroundParent MOZ_FINAL
{
friend class mozilla::dom::ContentParent;
typedef base::ProcessId ProcessId;
typedef mozilla::dom::ContentParent ContentParent;
typedef mozilla::ipc::Transport Transport;
private:
// Only called by ContentParent for cross-process actors.
static PBackgroundParent*
Alloc(ContentParent* aContent,
Transport* aTransport,
ProcessId aOtherProcess);
};
// Implemented in BackgroundImpl.cpp.
bool
IsOnBackgroundThread();
#ifdef DEBUG
// Implemented in BackgroundImpl.cpp.
void
AssertIsOnBackgroundThread();
#else
inline void
AssertIsOnBackgroundThread()
{ }
#endif // DEBUG
} // namespace ipc
} // namespace mozilla
#endif // mozilla_ipc_backgroundparent_h__

View File

@ -0,0 +1,117 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BackgroundParentImpl.h"
#include "mozilla/Assertions.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/ipc/PBackgroundTestParent.h"
#include "nsThreadUtils.h"
#include "nsTraceRefcnt.h"
#include "nsXULAppAPI.h"
using mozilla::ipc::AssertIsOnBackgroundThread;
namespace {
void
AssertIsInMainProcess()
{
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
}
void
AssertIsOnMainThread()
{
MOZ_ASSERT(NS_IsMainThread());
}
class TestParent MOZ_FINAL : public mozilla::ipc::PBackgroundTestParent
{
friend class mozilla::ipc::BackgroundParentImpl;
TestParent()
{
MOZ_COUNT_CTOR(mozilla::ipc::BackgroundTestParent);
}
~TestParent()
{
MOZ_COUNT_DTOR(mozilla::ipc::BackgroundTestParent);
}
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
};
} // anonymous namespace
namespace mozilla {
namespace ipc {
BackgroundParentImpl::BackgroundParentImpl()
{
AssertIsInMainProcess();
AssertIsOnMainThread();
MOZ_COUNT_CTOR(mozilla::ipc::BackgroundParentImpl);
}
BackgroundParentImpl::~BackgroundParentImpl()
{
AssertIsInMainProcess();
AssertIsOnMainThread();
MOZ_COUNT_DTOR(mozilla::ipc::BackgroundParentImpl);
}
void
BackgroundParentImpl::ActorDestroy(ActorDestroyReason aWhy)
{
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
}
PBackgroundTestParent*
BackgroundParentImpl::AllocPBackgroundTestParent(const nsCString& aTestArg)
{
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
return new TestParent();
}
bool
BackgroundParentImpl::RecvPBackgroundTestConstructor(
PBackgroundTestParent* aActor,
const nsCString& aTestArg)
{
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
MOZ_ASSERT(aActor);
return PBackgroundTestParent::Send__delete__(aActor, aTestArg);
}
bool
BackgroundParentImpl::DeallocPBackgroundTestParent(
PBackgroundTestParent* aActor)
{
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
MOZ_ASSERT(aActor);
delete static_cast<TestParent*>(aActor);
return true;
}
} // namespace ipc
} // namespace mozilla
void
TestParent::ActorDestroy(ActorDestroyReason aWhy)
{
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
}

View File

@ -0,0 +1,39 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_backgroundparentimpl_h__
#define mozilla_ipc_backgroundparentimpl_h__
#include "mozilla/Attributes.h"
#include "mozilla/ipc/PBackgroundParent.h"
namespace mozilla {
namespace ipc {
// Instances of this class should never be created directly. This class is meant
// to be inherited in BackgroundImpl.
class BackgroundParentImpl : public PBackgroundParent
{
protected:
BackgroundParentImpl();
virtual ~BackgroundParentImpl();
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual PBackgroundTestParent*
AllocPBackgroundTestParent(const nsCString& aTestArg) MOZ_OVERRIDE;
virtual bool
RecvPBackgroundTestConstructor(PBackgroundTestParent* aActor,
const nsCString& aTestArg) MOZ_OVERRIDE;
virtual bool
DeallocPBackgroundTestParent(PBackgroundTestParent* aActor) MOZ_OVERRIDE;
};
} // namespace ipc
} // namespace mozilla
#endif // mozilla_ipc_backgroundparentimpl_h__

View File

@ -428,8 +428,10 @@ MessageChannel::MaybeInterceptSpecialIOMessage(const Message& aMsg)
// :TODO: Sort out Close() on this side racing with Close() on the
// other side
mChannelState = ChannelClosing;
printf("NOTE: %s process received `Goodbye', closing down\n",
(mSide == ChildSide) ? "child" : "parent");
if (LoggingEnabled()) {
printf("NOTE: %s process received `Goodbye', closing down\n",
(mSide == ChildSide) ? "child" : "parent");
}
return true;
}
return false;
@ -1645,14 +1647,20 @@ MessageChannel::Close()
return;
}
if (ChannelOpening == mChannelState) {
// Mimic CloseWithError().
SynchronouslyClose();
mChannelState = ChannelError;
PostErrorNotifyTask();
return;
}
if (ChannelConnected != mChannelState) {
// XXX be strict about this until there's a compelling reason
// to relax
NS_RUNTIMEABORT("Close() called on closed channel!");
}
AssertWorkerThread();
// notify the other side that we're about to close our socket
mLink->SendMessage(new GoodbyeMessage());
SynchronouslyClose();
@ -1731,4 +1739,3 @@ MessageChannel::DumpInterruptStack(const char* const pfx) const
} // ipc
} // mozilla

20
ipc/glue/PBackground.ipdl Normal file
View File

@ -0,0 +1,20 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PBackgroundTest;
namespace mozilla {
namespace ipc {
protocol PBackground
{
manages PBackgroundTest;
parent:
// Only called at startup during mochitests to check the basic infrastructure.
PBackgroundTest(nsCString testArg);
};
} // namespace ipc
} // namespace mozilla

View File

@ -0,0 +1,20 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PBackground;
namespace mozilla {
namespace ipc {
// This is a very simple testing protocol that is only used during mochitests.
protocol PBackgroundTest
{
manager PBackground;
child:
__delete__(nsCString testArg);
};
} // namespace ipc
} // namespace mozilla

View File

@ -48,7 +48,7 @@ CreateTransport(ProcessHandle aProcOne, ProcessHandle /*unused*/,
aOne->mPipeName = aTwo->mPipeName = id;
aOne->mServerPipe = serverDup;
aTwo->mServerPipe = 0;
aTwo->mServerPipe = INVALID_HANDLE_VALUE;
return true;
}

View File

@ -5,11 +5,14 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS += [
'nsIIPCBackgroundChildCreateCallback.h',
'nsIIPCSerializableInputStream.h',
'nsIIPCSerializableURI.h',
]
EXPORTS.mozilla.ipc += [
'BackgroundChild.h',
'BackgroundParent.h',
'BrowserProcessSubThread.h',
'CrossProcessMutex.h',
'FileDescriptor.h',
@ -90,6 +93,7 @@ EXPORTS.ipc += [
]
UNIFIED_SOURCES += [
'BackgroundImpl.cpp',
'BrowserProcessSubThread.cpp',
'FileDescriptor.cpp',
'FileDescriptorUtils.cpp',
@ -108,12 +112,20 @@ UNIFIED_SOURCES += [
# GeckoChildProcessHost.cpp cannot be built in unified mode because it uses plarena.h.
# URIUtils.cpp cannot be built in unified mode because of name clashes on strdup.
SOURCES += [
'BackgroundChildImpl.cpp',
'BackgroundParentImpl.cpp',
'GeckoChildProcessHost.cpp',
'URIUtils.cpp',
]
LOCAL_INCLUDES += [
'/xpcom/build',
]
IPDL_SOURCES = [
'InputStreamParams.ipdlh',
'PBackground.ipdl',
'PBackgroundTest.ipdl',
'ProtocolTypes.ipdlh',
'URIParams.ipdlh',
]

View File

@ -0,0 +1,70 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_nsiipcbackgroundchildcreatecallback_h
#define mozilla_ipc_nsiipcbackgroundchildcreatecallback_h
#include "mozilla/Attributes.h"
#include "nsISupports.h"
namespace mozilla {
namespace ipc {
class PBackgroundChild;
} // namespace ipc
} // namespace mozilla
#define NS_IIPCBACKGROUNDCHILDCREATECALLBACK_IID \
{0x4de01707, 0x70e3, 0x4181, {0xbc, 0x9f, 0xa3, 0xec, 0xfe, 0x74, 0x1a, 0xe3}}
class NS_NO_VTABLE nsIIPCBackgroundChildCreateCallback : public nsISupports
{
public:
typedef mozilla::ipc::PBackgroundChild PBackgroundChild;
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IIPCBACKGROUNDCHILDCREATECALLBACK_IID)
// This will be called upon successful creation of a PBackgroundChild actor.
// The actor is unique per-thread and must not be shared across threads. It
// may be saved and reused on the same thread for as long as the thread lives.
// After this callback BackgroundChild::GetForCurrentThread() will return the
// same actor.
virtual void
ActorCreated(PBackgroundChild*) = 0;
// This will be called if for some reason the PBackgroundChild actor cannot be
// created. This should never be called in child processes as the failure to
// create the actor should result in the termination of the child process
// first. This may be called for cross-thread actors in the main process.
virtual void
ActorFailed() = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIIPCBackgroundChildCreateCallback,
NS_IIPCBACKGROUNDCHILDCREATECALLBACK_IID)
#define NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK \
virtual void \
ActorCreated(mozilla::ipc::PBackgroundChild*) MOZ_OVERRIDE; \
virtual void \
ActorFailed() MOZ_OVERRIDE;
#define NS_FORWARD_NSIIPCBACKGROUNDCHILDCREATECALLBACK(_to) \
virtual void \
ActorCreated(mozilla::ipc::PBackgroundChild* aActor) MOZ_OVERRIDE \
{ _to ActorCreated(aActor); } \
virtual void \
ActorFailed() MOZ_OVERRIDE \
{ _to ActorFailed(); }
#define NS_FORWARD_SAFE_NSIIPCBACKGROUNDCHILDCREATECALLBACK(_to) \
virtual void \
ActorCreated(mozilla::ipc::PBackgroundChild* aActor) MOZ_OVERRIDE \
{ if (_to) { _to->ActorCreated(aActor); } } \
virtual void \
ActorFailed() MOZ_OVERRIDE \
{ if (_to) { _to->ActorFailed(); } }
#endif // mozilla_ipc_nsiipcbackgroundchildcreatecallback_h

View File

@ -154,6 +154,9 @@ user_pref("browser.download.panel.shown", true);
// Disable first-tun tab
user_pref("browser.firstrun.count", 0);
// Tell the PBackground infrastructure to run a test at startup.
user_pref("pbackground.testing", true);
// Enable webapps testing mode, which bypasses native installation.
user_pref("browser.webapps.testing", true);