mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
Bug 1928734 - Part 2: Centralize handling of the IPC IO thread, r=ipc-reviewers,media-playback-reviewers,karlt,jld
Previously the handling for the IO thread was split between BrowserProcessSubThread (a replication of the background thread infrastructure used by Chromium during the IPC import, which is only used for the IO thread in Gecko), and IOThreadChild (a wrapper around ChildThread, which was imported from Chromium's source). This meant that there was little code-sharing between the parent and child processes, and that the lifecycle of the IO thread was perhaps less clear. This refactors the code to centralize handling of these threads, and provide a basic common interface. At the moment, actually hooking up async IO listeners is still done using the Chromium interfaces. Differential Revision: https://phabricator.services.mozilla.com/D227739
This commit is contained in:
parent
54b516eaa3
commit
42cf063288
@ -4,8 +4,6 @@
|
||||
* 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 "mozilla/ipc/IOThreadChild.h"
|
||||
|
||||
#include "ContentProcess.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
@ -22,8 +20,6 @@
|
||||
#include "mozilla/Omnijar.h"
|
||||
#include "nsCategoryManagerUtils.h"
|
||||
|
||||
using mozilla::ipc::IOThreadChild;
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
static nsresult GetGREDir(nsIFile** aResult) {
|
||||
|
@ -7,11 +7,8 @@
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/string_util.h"
|
||||
#include "mozilla/ipc/IOThreadChild.h"
|
||||
#include "mozilla/GeckoArgs.h"
|
||||
|
||||
using mozilla::ipc::IOThreadChild;
|
||||
|
||||
namespace mozilla::gmp {
|
||||
|
||||
/* static */ bool GMPProcessChild::sUseXpcom = false;
|
||||
|
@ -5,7 +5,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "RDDProcessImpl.h"
|
||||
|
||||
#include "mozilla/ipc/IOThreadChild.h"
|
||||
#include "mozilla/GeckoArgs.h"
|
||||
|
||||
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
|
||||
|
@ -4,7 +4,6 @@
|
||||
* 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 "GPUProcessImpl.h"
|
||||
#include "mozilla/ipc/IOThreadChild.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "mozilla/ipc/ProcessUtils.h"
|
||||
#include "mozilla/GeckoArgs.h"
|
||||
|
@ -8,13 +8,11 @@
|
||||
|
||||
#include "mozilla/BackgroundHangMonitor.h"
|
||||
#include "mozilla/GeckoArgs.h"
|
||||
#include "mozilla/ipc/IOThreadChild.h"
|
||||
#include "mozilla/ipc/ProcessUtils.h"
|
||||
#include "mozilla/StaticPrefs_dom.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using mozilla::ipc::IOThreadChild;
|
||||
|
||||
StaticRefPtr<VRParent> sVRParent;
|
||||
|
||||
|
@ -23,8 +23,6 @@ UNIFIED_SOURCES += [
|
||||
"src/base/thread.cc",
|
||||
"src/base/time.cc",
|
||||
"src/base/timer.cc",
|
||||
"src/chrome/common/child_process.cc",
|
||||
"src/chrome/common/child_thread.cc",
|
||||
"src/chrome/common/chrome_switches.cc",
|
||||
"src/chrome/common/ipc_channel_utils.cc",
|
||||
"src/chrome/common/ipc_message.cc",
|
||||
|
@ -1,29 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "chrome/common/child_process.h"
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/string_util.h"
|
||||
#include "chrome/common/child_thread.h"
|
||||
|
||||
ChildProcess* ChildProcess::child_process_;
|
||||
|
||||
ChildProcess::ChildProcess(ChildThread* child_thread)
|
||||
: child_thread_(child_thread) {
|
||||
DCHECK(!child_process_);
|
||||
child_process_ = this;
|
||||
if (child_thread_.get()) // null in unittests.
|
||||
child_thread_->Run();
|
||||
}
|
||||
|
||||
ChildProcess::~ChildProcess() {
|
||||
DCHECK(child_process_ == this);
|
||||
|
||||
if (child_thread_.get()) child_thread_->Stop();
|
||||
|
||||
child_process_ = NULL;
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_COMMON_CHILD_PROCESS_H__
|
||||
#define CHROME_COMMON_CHILD_PROCESS_H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "base/basictypes.h"
|
||||
#include "base/message_loop.h"
|
||||
#include "base/waitable_event.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
class ChildThread;
|
||||
|
||||
// Base class for child processes of the browser process (i.e. renderer and
|
||||
// plugin host). This is a singleton object for each child process.
|
||||
class ChildProcess {
|
||||
public:
|
||||
// Child processes should have an object that derives from this class. The
|
||||
// constructor will return once ChildThread has started.
|
||||
explicit ChildProcess(ChildThread* child_thread);
|
||||
virtual ~ChildProcess();
|
||||
|
||||
// Getter for this process' main thread.
|
||||
ChildThread* child_thread() { return child_thread_.get(); }
|
||||
|
||||
// Getter for the one ChildProcess object for this process.
|
||||
static ChildProcess* current() { return child_process_; }
|
||||
|
||||
private:
|
||||
// NOTE: make sure that child_thread_ is listed before shutdown_event_, since
|
||||
// it depends on it (indirectly through IPC::SyncChannel).
|
||||
mozilla::UniquePtr<ChildThread> child_thread_;
|
||||
|
||||
// The singleton instance for this process.
|
||||
static ChildProcess* child_process_;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(ChildProcess);
|
||||
};
|
||||
|
||||
#endif // CHROME_COMMON_CHILD_PROCESS_H__
|
@ -1,49 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "chrome/common/child_thread.h"
|
||||
|
||||
#include "chrome/common/child_process.h"
|
||||
#include "mozilla/ipc/NodeController.h"
|
||||
|
||||
ChildThread::ChildThread(Thread::Options options,
|
||||
IPC::Channel::ChannelHandle client_handle,
|
||||
base::ProcessId parent_pid)
|
||||
: Thread("IPC I/O Child"),
|
||||
owner_loop_(MessageLoop::current()),
|
||||
options_(options),
|
||||
client_handle_(std::move(client_handle)),
|
||||
parent_pid_(parent_pid) {
|
||||
DCHECK(owner_loop_);
|
||||
}
|
||||
|
||||
ChildThread::~ChildThread() = default;
|
||||
|
||||
bool ChildThread::Run() {
|
||||
bool r = StartWithOptions(options_);
|
||||
return r;
|
||||
}
|
||||
|
||||
ChildThread* ChildThread::current() {
|
||||
return ChildProcess::current()->child_thread();
|
||||
}
|
||||
|
||||
void ChildThread::Init() {
|
||||
// Take ownership of the client channel handle which we inherited, and use it
|
||||
// to start the initial IPC connection to the parent process.
|
||||
auto channel = mozilla::MakeUnique<IPC::Channel>(
|
||||
std::move(client_handle_), IPC::Channel::MODE_CLIENT, parent_pid_);
|
||||
#if defined(XP_WIN)
|
||||
channel->StartAcceptingHandles(IPC::Channel::MODE_CLIENT);
|
||||
#elif defined(XP_DARWIN)
|
||||
channel->StartAcceptingMachPorts(IPC::Channel::MODE_CLIENT);
|
||||
#endif
|
||||
|
||||
initial_port_ = mozilla::ipc::NodeController::InitChildProcess(
|
||||
std::move(channel), parent_pid_);
|
||||
}
|
||||
|
||||
void ChildThread::CleanUp() { mozilla::ipc::NodeController::CleanUp(); }
|
@ -1,60 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_COMMON_CHILD_THREAD_H_
|
||||
#define CHROME_COMMON_CHILD_THREAD_H_
|
||||
|
||||
#include "base/thread.h"
|
||||
#include "chrome/common/ipc_channel.h"
|
||||
#include "mojo/core/ports/port_ref.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/ipc/ScopedPort.h"
|
||||
|
||||
class ResourceDispatcher;
|
||||
|
||||
// Child processes's background thread should derive from this class.
|
||||
class ChildThread : public base::Thread {
|
||||
public:
|
||||
// Creates the thread.
|
||||
ChildThread(Thread::Options options,
|
||||
IPC::Channel::ChannelHandle client_handle,
|
||||
base::ProcessId parent_pid);
|
||||
virtual ~ChildThread();
|
||||
|
||||
mozilla::ipc::ScopedPort TakeInitialPort() {
|
||||
return std::move(initial_port_);
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class ChildProcess;
|
||||
|
||||
// Starts the thread.
|
||||
bool Run();
|
||||
|
||||
protected:
|
||||
// Returns the one child thread.
|
||||
static ChildThread* current();
|
||||
|
||||
// Thread implementation.
|
||||
virtual void Init() override;
|
||||
virtual void CleanUp() override;
|
||||
|
||||
private:
|
||||
// The message loop used to run tasks on the thread that started this thread.
|
||||
MessageLoop* owner_loop_;
|
||||
|
||||
mozilla::ipc::ScopedPort initial_port_;
|
||||
|
||||
Thread::Options options_;
|
||||
|
||||
IPC::Channel::ChannelHandle client_handle_;
|
||||
|
||||
base::ProcessId parent_pid_;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(ChildThread);
|
||||
};
|
||||
|
||||
#endif // CHROME_COMMON_CHILD_THREAD_H_
|
@ -1,83 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 "mozilla/ipc/BrowserProcessSubThread.h"
|
||||
#include "mozilla/ipc/NodeController.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
# include <objbase.h>
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
//
|
||||
// BrowserProcessSubThread
|
||||
//
|
||||
|
||||
// Friendly names for the well-known threads.
|
||||
static const char* kBrowserThreadNames[BrowserProcessSubThread::ID_COUNT] = {
|
||||
"IPC I/O Parent", // IO
|
||||
};
|
||||
|
||||
/* static */
|
||||
StaticMutex BrowserProcessSubThread::sLock;
|
||||
BrowserProcessSubThread* BrowserProcessSubThread::sBrowserThreads[ID_COUNT] = {
|
||||
nullptr, // IO
|
||||
};
|
||||
|
||||
BrowserProcessSubThread::BrowserProcessSubThread(ID aId)
|
||||
: base::Thread(kBrowserThreadNames[aId]), mIdentifier(aId) {
|
||||
StaticMutexAutoLock lock(sLock);
|
||||
DCHECK(aId >= 0 && aId < ID_COUNT);
|
||||
DCHECK(sBrowserThreads[aId] == nullptr);
|
||||
sBrowserThreads[aId] = this;
|
||||
}
|
||||
|
||||
BrowserProcessSubThread::~BrowserProcessSubThread() {
|
||||
Stop();
|
||||
{
|
||||
StaticMutexAutoLock lock(sLock);
|
||||
sBrowserThreads[mIdentifier] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserProcessSubThread::Init() {
|
||||
#if defined(XP_WIN)
|
||||
// Initializes the COM library on the current thread.
|
||||
CoInitialize(nullptr);
|
||||
#endif
|
||||
|
||||
// Initialize the ports library in the current thread.
|
||||
if (mIdentifier == IO) {
|
||||
NodeController::InitBrokerProcess();
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserProcessSubThread::CleanUp() {
|
||||
if (mIdentifier == IO) {
|
||||
NodeController::CleanUp();
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
// Closes the COM library on the current thread. CoInitialize must
|
||||
// be balanced by a corresponding call to CoUninitialize.
|
||||
CoUninitialize();
|
||||
#endif
|
||||
}
|
||||
|
||||
// static
|
||||
MessageLoop* BrowserProcessSubThread::GetMessageLoop(ID aId) {
|
||||
StaticMutexAutoLock lock(sLock);
|
||||
DCHECK(aId >= 0 && aId < ID_COUNT);
|
||||
|
||||
if (sBrowserThreads[aId]) return sBrowserThreads[aId]->message_loop();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
@ -1,66 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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_BrowserProcessSubThread_h
|
||||
#define mozilla_ipc_BrowserProcessSubThread_h
|
||||
|
||||
#include "base/thread.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
|
||||
#include "nsDebug.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
// Copied from browser_process_impl.cc, modified slightly.
|
||||
class BrowserProcessSubThread : public base::Thread {
|
||||
public:
|
||||
// An enumeration of the well-known threads.
|
||||
enum ID {
|
||||
IO,
|
||||
|
||||
// This identifier does not represent a thread. Instead it counts
|
||||
// the number of well-known threads. Insert new well-known
|
||||
// threads before this identifier.
|
||||
ID_COUNT
|
||||
};
|
||||
|
||||
explicit BrowserProcessSubThread(ID aId);
|
||||
~BrowserProcessSubThread();
|
||||
|
||||
static MessageLoop* GetMessageLoop(ID identifier);
|
||||
|
||||
protected:
|
||||
virtual void Init() override;
|
||||
virtual void CleanUp() override;
|
||||
|
||||
private:
|
||||
// The identifier of this thread. Only one thread can exist with a given
|
||||
// identifier at a given time.
|
||||
ID mIdentifier;
|
||||
|
||||
// This lock protects |browser_threads_|. Do not read or modify that array
|
||||
// without holding this lock. Do not block while holding this lock.
|
||||
|
||||
static StaticMutex sLock;
|
||||
|
||||
// An array of the ChromeThread objects. This array is protected by |lock_|.
|
||||
// The threads are not owned by this array. Typically, the threads are owned
|
||||
// on the UI thread by the g_browser_process object. ChromeThreads remove
|
||||
// themselves from this array upon destruction.
|
||||
static BrowserProcessSubThread* sBrowserThreads[ID_COUNT] MOZ_GUARDED_BY(
|
||||
sLock);
|
||||
};
|
||||
|
||||
inline void AssertIOThread() {
|
||||
MOZ_ASSERT(XRE_GetAsyncIOEventTarget()->IsOnCurrentThread(),
|
||||
"should be on the async IO event target");
|
||||
}
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_ipc_BrowserProcessSubThread_h
|
@ -55,7 +55,7 @@
|
||||
#include "mozilla/glean/GleanMetrics.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/UniquePtrExtensions.h"
|
||||
#include "mozilla/ipc/BrowserProcessSubThread.h"
|
||||
#include "mozilla/ipc/IOThread.h"
|
||||
#include "mozilla/ipc/EnvironmentMap.h"
|
||||
#include "mozilla/ipc/NodeController.h"
|
||||
#include "mozilla/net/SocketProcessHost.h"
|
||||
|
107
ipc/glue/IOThread.cpp
Normal file
107
ipc/glue/IOThread.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 "mozilla/ipc/IOThread.h"
|
||||
#include "mozilla/ipc/NodeController.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
# include <objbase.h>
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
//
|
||||
// IOThread
|
||||
//
|
||||
|
||||
/* static */
|
||||
IOThread* IOThread::sSingleton = nullptr;
|
||||
|
||||
IOThread::IOThread(const char* aName) : base::Thread(aName) {
|
||||
sSingleton = this;
|
||||
}
|
||||
|
||||
IOThread::~IOThread() {
|
||||
MOZ_ASSERT(!IsRunning());
|
||||
sSingleton = nullptr;
|
||||
}
|
||||
|
||||
void IOThread::StartThread() {
|
||||
// Failure to create the IPC I/O thread is unrecoverable.
|
||||
// NOTE: This will block if successful for the `Init()` virtual method to have
|
||||
// been run.
|
||||
if (!StartWithOptions(
|
||||
base::Thread::Options{MessageLoop::TYPE_IO, /* stack size */ 0})) {
|
||||
MOZ_CRASH("Failed to create IPC I/O Thread");
|
||||
}
|
||||
}
|
||||
|
||||
void IOThread::StopThread() {
|
||||
// This will block until CleanUp() has been called, and the IPC I/O thread has
|
||||
// been joined.
|
||||
Stop();
|
||||
}
|
||||
|
||||
//
|
||||
// IOThreadParent
|
||||
//
|
||||
|
||||
IOThreadParent::IOThreadParent() : IOThread("IPC I/O Parent") { StartThread(); }
|
||||
|
||||
IOThreadParent::~IOThreadParent() { StopThread(); }
|
||||
|
||||
void IOThreadParent::Init() {
|
||||
#if defined(XP_WIN)
|
||||
// Initializes the COM library on the current thread.
|
||||
CoInitialize(nullptr);
|
||||
#endif
|
||||
|
||||
// Initialize the ports library in the current thread.
|
||||
NodeController::InitBrokerProcess();
|
||||
}
|
||||
|
||||
void IOThreadParent::CleanUp() {
|
||||
NodeController::CleanUp();
|
||||
|
||||
#if defined(XP_WIN)
|
||||
// Closes the COM library on the current thread. CoInitialize must
|
||||
// be balanced by a corresponding call to CoUninitialize.
|
||||
CoUninitialize();
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// IOThreadChild
|
||||
//
|
||||
|
||||
IOThreadChild::IOThreadChild(IPC::Channel::ChannelHandle aClientHandle,
|
||||
base::ProcessId aParentPid)
|
||||
: IOThread("IPC I/O Child"),
|
||||
mClientHandle(std::move(aClientHandle)),
|
||||
mParentPid(std::move(aParentPid)) {
|
||||
StartThread();
|
||||
}
|
||||
|
||||
IOThreadChild::~IOThreadChild() { StopThread(); }
|
||||
|
||||
void IOThreadChild::Init() {
|
||||
auto channel = MakeUnique<IPC::Channel>(
|
||||
std::move(mClientHandle), IPC::Channel::MODE_CLIENT, mParentPid);
|
||||
#if defined(XP_WIN)
|
||||
channel->StartAcceptingHandles(IPC::Channel::MODE_CLIENT);
|
||||
#elif defined(XP_DARWIN)
|
||||
channel->StartAcceptingMachPorts(IPC::Channel::MODE_CLIENT);
|
||||
#endif
|
||||
|
||||
mInitialPort = mozilla::ipc::NodeController::InitChildProcess(
|
||||
std::move(channel), mParentPid);
|
||||
}
|
||||
|
||||
void IOThreadChild::CleanUp() { NodeController::CleanUp(); }
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
88
ipc/glue/IOThread.h
Normal file
88
ipc/glue/IOThread.h
Normal file
@ -0,0 +1,88 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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_IOThreadParent_h
|
||||
#define mozilla_ipc_IOThreadParent_h
|
||||
|
||||
#include "base/thread.h"
|
||||
#include "chrome/common/ipc_channel.h"
|
||||
#include "mozilla/ipc/ScopedPort.h"
|
||||
|
||||
namespace mozilla::ipc {
|
||||
|
||||
// Abstract background thread used for IPC I/O.
|
||||
class IOThread : private base::Thread {
|
||||
public:
|
||||
// Lifecycle Note: The IOThread is stored in a static, and is returned by raw
|
||||
// pointer here from potentially any thread. This is OK because the IOThread
|
||||
// is very long lived, and should outlive any other thread which would
|
||||
// reference it (other than the main thread, which is responsible for the
|
||||
// lifetime of the IO Thread).
|
||||
static IOThread* Get() { return sSingleton; }
|
||||
|
||||
// Get the nsISerialEventTarget which should be used to dispatch events to run
|
||||
// on the IOThreadBase.
|
||||
nsISerialEventTarget* GetEventTarget() {
|
||||
return base::Thread::message_loop()->SerialEventTarget();
|
||||
}
|
||||
|
||||
protected:
|
||||
IOThread(const char* aName);
|
||||
~IOThread();
|
||||
|
||||
// Called by subclasses in the constructor/destructor to start/join the target
|
||||
// thread. This cannot be done in the base class constructor/destructor, as
|
||||
// the virtual Init()/CleanUp() methods need to be available.
|
||||
void StartThread();
|
||||
void StopThread();
|
||||
|
||||
// Init() and Cleanup() methods which will be invoked on the IOThread when the
|
||||
// IOThread is started/stopped.
|
||||
void Init() override = 0;
|
||||
void CleanUp() override = 0;
|
||||
|
||||
private:
|
||||
static IOThread* sSingleton;
|
||||
};
|
||||
|
||||
// Background I/O thread used by the parent process.
|
||||
class IOThreadParent : public IOThread {
|
||||
public:
|
||||
IOThreadParent();
|
||||
~IOThreadParent();
|
||||
|
||||
protected:
|
||||
void Init() override;
|
||||
void CleanUp() override;
|
||||
};
|
||||
|
||||
// Background I/O thread used by the child process.
|
||||
class IOThreadChild : public IOThread {
|
||||
public:
|
||||
IOThreadChild(IPC::Channel::ChannelHandle aClientHandle,
|
||||
base::ProcessId aParentPid);
|
||||
~IOThreadChild();
|
||||
|
||||
mozilla::ipc::ScopedPort TakeInitialPort() { return std::move(mInitialPort); }
|
||||
|
||||
protected:
|
||||
void Init() override;
|
||||
void CleanUp() override;
|
||||
|
||||
private:
|
||||
mozilla::ipc::ScopedPort mInitialPort;
|
||||
IPC::Channel::ChannelHandle mClientHandle;
|
||||
base::ProcessId mParentPid;
|
||||
};
|
||||
|
||||
inline void AssertIOThread() {
|
||||
MOZ_ASSERT(IOThread::Get()->GetEventTarget()->IsOnCurrentThread(),
|
||||
"should be on the async IO event target");
|
||||
}
|
||||
|
||||
} // namespace mozilla::ipc
|
||||
|
||||
#endif // mozilla_ipc_IOThreadParent_h
|
@ -1,47 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 dom_plugins_IOThreadChild_h
|
||||
#define dom_plugins_IOThreadChild_h
|
||||
|
||||
#include "chrome/common/child_thread.h"
|
||||
#include "mozilla/ipc/Endpoint.h"
|
||||
#include "mozilla/ipc/NodeController.h"
|
||||
#include "mozilla/ipc/ProcessChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// The IOThreadChild class represents a background thread where the
|
||||
// IPC IO MessageLoop lives.
|
||||
class IOThreadChild : public ChildThread {
|
||||
public:
|
||||
explicit IOThreadChild(IPC::Channel::ChannelHandle aClientChannel,
|
||||
base::ProcessId aParentPid)
|
||||
: ChildThread(base::Thread::Options(MessageLoop::TYPE_IO,
|
||||
/* stack size */ 0),
|
||||
std::move(aClientChannel), aParentPid) {}
|
||||
|
||||
~IOThreadChild() = default;
|
||||
|
||||
static MessageLoop* message_loop() {
|
||||
return IOThreadChild::current()->Thread::message_loop();
|
||||
}
|
||||
|
||||
protected:
|
||||
static IOThreadChild* current() {
|
||||
return static_cast<IOThreadChild*>(ChildThread::current());
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_EVIL_CONSTRUCTORS(IOThreadChild);
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // ifndef dom_plugins_IOThreadChild_h
|
@ -12,6 +12,7 @@
|
||||
#include <utility>
|
||||
|
||||
#include "CrashAnnotations.h"
|
||||
#include "base/waitable_event.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/CycleCollectedJSContext.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "mojo/core/ports/event.h"
|
||||
#include "mojo/core/ports/node.h"
|
||||
#include "mozilla/ipc/MessageChannel.h"
|
||||
#include "mozilla/ipc/BrowserProcessSubThread.h"
|
||||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
#include "mozilla/ipc/NodeController.h"
|
||||
#include "chrome/common/ipc_channel.h"
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "chrome/common/ipc_message.h"
|
||||
#include "chrome/common/ipc_message_utils.h"
|
||||
#include "mojo/core/ports/name.h"
|
||||
#include "mozilla/ipc/BrowserProcessSubThread.h"
|
||||
#include "mozilla/ipc/IOThread.h"
|
||||
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
||||
#include "mozilla/ipc/ProtocolMessageUtils.h"
|
||||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/ToString.h"
|
||||
#include "mozilla/ipc/BrowserProcessSubThread.h"
|
||||
#include "mozilla/ipc/IOThread.h"
|
||||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
#include "mozilla/mozalloc.h"
|
||||
#include "nsISerialEventTarget.h"
|
||||
|
@ -21,7 +21,8 @@
|
||||
|
||||
#include "nsAppRunner.h"
|
||||
#include "mozilla/AppShutdown.h"
|
||||
#include "mozilla/ipc/IOThreadChild.h"
|
||||
#include "mozilla/ipc/IOThread.h"
|
||||
#include "mozilla/ipc/ProcessUtils.h"
|
||||
#include "mozilla/GeckoArgs.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -35,10 +36,11 @@ static Atomic<bool> sExpectingShutdown(false);
|
||||
|
||||
ProcessChild::ProcessChild(IPC::Channel::ChannelHandle aClientChannel,
|
||||
ProcessId aParentPid, const nsID& aMessageChannelId)
|
||||
: ChildProcess(new IOThreadChild(std::move(aClientChannel), aParentPid)),
|
||||
mUILoop(MessageLoop::current()),
|
||||
: mUILoop(MessageLoop::current()),
|
||||
mParentPid(aParentPid),
|
||||
mMessageChannelId(aMessageChannelId) {
|
||||
mMessageChannelId(aMessageChannelId),
|
||||
mChildThread(
|
||||
MakeUnique<IOThreadChild>(std::move(aClientChannel), aParentPid)) {
|
||||
MOZ_ASSERT(mUILoop, "UILoop should be created by now");
|
||||
MOZ_ASSERT(!gProcessChild, "should only be one ProcessChild");
|
||||
CrashReporter::RegisterAnnotationNSCString(
|
||||
@ -129,7 +131,7 @@ void ProcessChild::QuickExit() {
|
||||
|
||||
UntypedEndpoint ProcessChild::TakeInitialEndpoint() {
|
||||
return UntypedEndpoint{PrivateIPDLInterface{},
|
||||
child_thread()->TakeInitialPort(), mMessageChannelId,
|
||||
mChildThread->TakeInitialPort(), mMessageChannelId,
|
||||
EndpointProcInfo::Current(),
|
||||
EndpointProcInfo{.mPid = mParentPid, .mChildID = 0}};
|
||||
}
|
||||
|
@ -11,9 +11,8 @@
|
||||
#include "base/message_loop.h"
|
||||
#include "base/process.h"
|
||||
|
||||
#include "chrome/common/child_process.h"
|
||||
|
||||
#include "mozilla/ipc/ProcessUtils.h"
|
||||
#include "mozilla/GeckoArgs.h"
|
||||
#include "mozilla/ipc/IOThread.h"
|
||||
|
||||
// ProcessChild is the base class for all subprocesses of the main
|
||||
// browser process. Its code runs on the thread that started in
|
||||
@ -22,7 +21,7 @@
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
class ProcessChild : public ChildProcess {
|
||||
class ProcessChild {
|
||||
protected:
|
||||
typedef base::ProcessId ProcessId;
|
||||
|
||||
@ -77,6 +76,7 @@ class ProcessChild : public ChildProcess {
|
||||
MessageLoop* mUILoop;
|
||||
ProcessId mParentPid;
|
||||
nsID mMessageChannelId;
|
||||
UniquePtr<IOThreadChild> mChildThread;
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
|
@ -5,7 +5,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "UtilityProcessImpl.h"
|
||||
|
||||
#include "mozilla/ipc/IOThreadChild.h"
|
||||
#include "mozilla/GeckoArgs.h"
|
||||
#include "mozilla/ProcInfo.h"
|
||||
|
||||
|
@ -17,7 +17,6 @@ EXPORTS.mozilla.ipc += [
|
||||
"BackgroundStarterParent.h",
|
||||
"BackgroundUtils.h",
|
||||
"BigBuffer.h",
|
||||
"BrowserProcessSubThread.h",
|
||||
"ByteBuf.h",
|
||||
"ByteBufUtils.h",
|
||||
"CrashReporterClient.h",
|
||||
@ -34,7 +33,7 @@ EXPORTS.mozilla.ipc += [
|
||||
"IdleSchedulerChild.h",
|
||||
"IdleSchedulerParent.h",
|
||||
"InputStreamUtils.h",
|
||||
"IOThreadChild.h",
|
||||
"IOThread.h",
|
||||
"IPCCore.h",
|
||||
"IPCForwards.h",
|
||||
"IPCStreamUtils.h",
|
||||
@ -166,7 +165,6 @@ UNIFIED_SOURCES += [
|
||||
"BackgroundImpl.cpp",
|
||||
"BackgroundUtils.cpp",
|
||||
"BigBuffer.cpp",
|
||||
"BrowserProcessSubThread.cpp",
|
||||
"CrashReporterClient.cpp",
|
||||
"CrashReporterHost.cpp",
|
||||
"DataPipe.cpp",
|
||||
@ -176,6 +174,7 @@ UNIFIED_SOURCES += [
|
||||
"IdleSchedulerChild.cpp",
|
||||
"IdleSchedulerParent.cpp",
|
||||
"InputStreamUtils.cpp",
|
||||
"IOThread.cpp",
|
||||
"IPCMessageUtilsSpecializations.cpp",
|
||||
"IPCStreamUtils.cpp",
|
||||
"MessageChannel.cpp",
|
||||
|
@ -7,10 +7,10 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "mozilla/_ipdltest/IPDLUnitTest.h"
|
||||
#include "mozilla/ipc/IOThreadChild.h"
|
||||
#include "mozilla/ipc/NodeController.h"
|
||||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
#include "mozilla/ipc/ProcessChild.h"
|
||||
#include "mozilla/ipc/ProcessUtils.h"
|
||||
#include "mozilla/SpinEventLoopUntil.h"
|
||||
#include "nsDebugImpl.h"
|
||||
#include "nsThreadManager.h"
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/GeckoArgs.h"
|
||||
#include "mozilla/ipc/ProcessUtils.h"
|
||||
#include "mozilla/ipc/IOThreadChild.h"
|
||||
|
||||
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
|
||||
# include "mozilla/sandboxTarget.h"
|
||||
@ -24,8 +23,6 @@
|
||||
# include <unistd.h> // For sleep().
|
||||
#endif
|
||||
|
||||
using mozilla::ipc::IOThreadChild;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
|
@ -69,8 +69,7 @@
|
||||
#include "mozilla/ipc/UtilityProcessImpl.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "mozilla/ipc/BrowserProcessSubThread.h"
|
||||
#include "mozilla/ipc/IOThreadChild.h"
|
||||
#include "mozilla/ipc/IOThread.h"
|
||||
#include "mozilla/ipc/ProcessChild.h"
|
||||
|
||||
#include "mozilla/dom/ContentProcess.h"
|
||||
@ -129,9 +128,8 @@
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
using mozilla::ipc::BrowserProcessSubThread;
|
||||
using mozilla::ipc::GeckoChildProcessHost;
|
||||
using mozilla::ipc::IOThreadChild;
|
||||
using mozilla::ipc::IOThread;
|
||||
using mozilla::ipc::ProcessChild;
|
||||
|
||||
using mozilla::dom::ContentParent;
|
||||
@ -598,14 +596,7 @@ nsresult XRE_InitChildProcess(int aArgc, char* aArgv[],
|
||||
}
|
||||
|
||||
nsISerialEventTarget* XRE_GetAsyncIOEventTarget() {
|
||||
// FIXME: Consider cleaning up the IO thread situation.
|
||||
MessageLoop* loop = nullptr;
|
||||
if (GetGeckoProcessType() == GeckoProcessType_Default) {
|
||||
loop = BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO);
|
||||
} else {
|
||||
loop = IOThreadChild::message_loop();
|
||||
}
|
||||
return loop ? loop->SerialEventTarget() : nullptr;
|
||||
return IOThread::Get()->GetEventTarget();
|
||||
}
|
||||
|
||||
nsresult XRE_RunAppShell() {
|
||||
|
@ -88,7 +88,7 @@
|
||||
#include "base/command_line.h"
|
||||
#include "base/message_loop.h"
|
||||
|
||||
#include "mozilla/ipc/BrowserProcessSubThread.h"
|
||||
#include "mozilla/ipc/IOThread.h"
|
||||
#include "mozilla/AvailableMemoryTracker.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/CountingAllocatorBase.h"
|
||||
@ -114,7 +114,7 @@
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
using base::AtExitManager;
|
||||
using mozilla::ipc::BrowserProcessSubThread;
|
||||
using mozilla::ipc::IOThreadParent;
|
||||
|
||||
// From toolkit/library/rust/lib.rs
|
||||
extern "C" void GkRust_Init();
|
||||
@ -125,7 +125,7 @@ namespace {
|
||||
static AtExitManager* sExitManager;
|
||||
static MessageLoop* sMessageLoop;
|
||||
static bool sCommandLineWasInitialized;
|
||||
static BrowserProcessSubThread* sIOThread;
|
||||
static IOThreadParent* sIOThread;
|
||||
static mozilla::BackgroundHangMonitor* sMainHangMonitor;
|
||||
|
||||
} /* anonymous namespace */
|
||||
@ -313,20 +313,12 @@ NS_InitXPCOM(nsIServiceManager** aResult, nsIFile* aBinDirectory,
|
||||
messageLoop->set_hang_timeouts(128, 8192);
|
||||
}
|
||||
|
||||
if (XRE_IsParentProcess() &&
|
||||
!BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)) {
|
||||
mozilla::UniquePtr<BrowserProcessSubThread> ioThread =
|
||||
mozilla::MakeUnique<BrowserProcessSubThread>(
|
||||
BrowserProcessSubThread::IO);
|
||||
|
||||
base::Thread::Options options;
|
||||
options.message_loop_type = MessageLoop::TYPE_IO;
|
||||
if (NS_WARN_IF(!ioThread->StartWithOptions(options))) {
|
||||
XPCOM_INIT_FATAL("StartWithOptions()", NS_ERROR_FAILURE)
|
||||
}
|
||||
|
||||
sIOThread = ioThread.release();
|
||||
// Start the IPC I/O thread in the parent process. We'll have already started
|
||||
// the IPC I/O thread if we're in a content process.
|
||||
if (XRE_IsParentProcess()) {
|
||||
sIOThread = new IOThreadParent();
|
||||
}
|
||||
MOZ_ASSERT(mozilla::ipc::IOThread::Get(), "An IOThread has been started");
|
||||
|
||||
// Establish the main thread here.
|
||||
rv = nsThreadManager::get().Init();
|
||||
|
Loading…
Reference in New Issue
Block a user