tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

IOThread.cpp (3432B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "mozilla/ipc/IOThread.h"
      8 #include "mozilla/ipc/NodeController.h"
      9 #include "mozilla/Preferences.h"
     10 
     11 #if defined(XP_WIN)
     12 #  include <objbase.h>
     13 #endif
     14 
     15 #if defined(XP_WIN)
     16 #  include "chrome/common/ipc_channel_win.h"
     17 #else
     18 #  if defined(XP_DARWIN)
     19 #    include "chrome/common/ipc_channel_mach.h"
     20 #  endif
     21 #  include "chrome/common/ipc_channel_posix.h"
     22 #endif
     23 
     24 namespace mozilla {
     25 namespace ipc {
     26 
     27 //
     28 // IOThread
     29 //
     30 
     31 /* static */
     32 IOThread* IOThread::sSingleton = nullptr;
     33 
     34 IOThread::IOThread(const char* aName) : base::Thread(aName) {
     35  sSingleton = this;
     36 }
     37 
     38 IOThread::~IOThread() {
     39  MOZ_ASSERT(!IsRunning());
     40  sSingleton = nullptr;
     41 }
     42 
     43 void IOThread::Startup() {
     44  if (XRE_IsParentProcess()) {
     45    // Destroyed in IOThread::Shutdown
     46    auto* thread = new IOThreadParent();
     47    MOZ_RELEASE_ASSERT(thread == sSingleton);
     48  }
     49  MOZ_ASSERT(sSingleton);
     50 }
     51 
     52 void IOThread::Shutdown() {
     53  if (XRE_IsParentProcess()) {
     54    delete static_cast<IOThreadParent*>(sSingleton);
     55    MOZ_ASSERT(!sSingleton);
     56  }
     57 }
     58 
     59 void IOThread::StartThread() {
     60  // Failure to create the IPC I/O thread is unrecoverable.
     61  // NOTE: This will block if successful for the `Init()` virtual method to have
     62  // been run.
     63  if (!StartWithOptions(
     64          base::Thread::Options{MessageLoop::TYPE_IO, /* stack size */ 0})) {
     65    MOZ_CRASH("Failed to create IPC I/O Thread");
     66  }
     67 }
     68 
     69 void IOThread::StopThread() {
     70  // This will block until CleanUp() has been called, and the IPC I/O thread has
     71  // been joined.
     72  Stop();
     73 }
     74 
     75 //
     76 // IOThreadParent
     77 //
     78 
     79 IOThreadParent::IOThreadParent() : IOThread("IPC I/O Parent") {
     80  MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
     81 
     82  // Select which type of channel will be used for IPC.
     83  mChannelKind = [] {
     84 #if defined(XP_WIN)
     85    return &IPC::ChannelWin::sKind;
     86 #else
     87 #  if defined(XP_DARWIN)
     88    if (Preferences::GetBool("dom.ipc.backend.mach")) {
     89      return &IPC::ChannelMach::sKind;
     90    }
     91 #  endif
     92    return &IPC::ChannelPosix::sKind;
     93 #endif
     94  }();
     95 
     96  StartThread();
     97 }
     98 
     99 IOThreadParent::~IOThreadParent() { StopThread(); }
    100 
    101 void IOThreadParent::Init() {
    102 #if defined(XP_WIN)
    103  // Initializes the COM library on the current thread.
    104  CoInitialize(nullptr);
    105 #endif
    106 
    107  // Initialize the ports library in the current thread.
    108  NodeController::InitBrokerProcess(mChannelKind);
    109 }
    110 
    111 void IOThreadParent::CleanUp() {
    112  NodeController::CleanUp();
    113 
    114 #if defined(XP_WIN)
    115  // Closes the COM library on the current thread. CoInitialize must
    116  // be balanced by a corresponding call to CoUninitialize.
    117  CoUninitialize();
    118 #endif
    119 }
    120 
    121 //
    122 // IOThreadChild
    123 //
    124 
    125 IOThreadChild::IOThreadChild(IPC::Channel::ChannelHandle aClientHandle,
    126                             base::ProcessId aParentPid)
    127    : IOThread("IPC I/O Child"),
    128      mClientHandle(std::move(aClientHandle)),
    129      mParentPid(std::move(aParentPid)) {
    130  StartThread();
    131 }
    132 
    133 IOThreadChild::~IOThreadChild() { StopThread(); }
    134 
    135 void IOThreadChild::Init() {
    136  mInitialPort =
    137      NodeController::InitChildProcess(std::move(mClientHandle), mParentPid);
    138 }
    139 
    140 void IOThreadChild::CleanUp() { NodeController::CleanUp(); }
    141 
    142 }  // namespace ipc
    143 }  // namespace mozilla