tor-browser

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

MessagePump.h (5783B)


      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 #ifndef __IPC_GLUE_MESSAGEPUMP_H__
      8 #define __IPC_GLUE_MESSAGEPUMP_H__
      9 
     10 #include "base/message_pump_default.h"
     11 #if defined(XP_WIN)
     12 #  include "base/message_pump_win.h"
     13 #elif defined(XP_DARWIN)
     14 #  include "base/message_pump_mac.h"
     15 #endif
     16 
     17 #include "base/time.h"
     18 #include "mozilla/Mutex.h"
     19 #include "nsCOMPtr.h"
     20 #include "nsIThreadInternal.h"
     21 
     22 class nsIEventTarget;
     23 class nsITimer;
     24 
     25 namespace mozilla {
     26 namespace ipc {
     27 
     28 class DoWorkRunnable;
     29 
     30 class MessagePump : public base::MessagePumpDefault {
     31  friend class DoWorkRunnable;
     32 
     33 public:
     34  explicit MessagePump(nsISerialEventTarget* aEventTarget);
     35 
     36  // From base::MessagePump.
     37  virtual void Run(base::MessagePump::Delegate* aDelegate) override;
     38 
     39  // From base::MessagePump.
     40  virtual void ScheduleWork() override;
     41 
     42  // From base::MessagePump.
     43  virtual void ScheduleWorkForNestedLoop() override;
     44 
     45  // From base::MessagePump.
     46  virtual void ScheduleDelayedWork(
     47      const base::TimeTicks& aDelayedWorkTime) override;
     48 
     49  virtual nsISerialEventTarget* GetXPCOMThread() override;
     50 
     51 protected:
     52  virtual ~MessagePump();
     53 
     54 private:
     55  // Only called by DoWorkRunnable.
     56  void DoDelayedWork(base::MessagePump::Delegate* aDelegate);
     57 
     58 protected:
     59  nsISerialEventTarget* mEventTarget;
     60 
     61  // mDelayedWorkTimer and mEventTarget are set in Run() by this class or its
     62  // subclasses.
     63  nsCOMPtr<nsITimer> mDelayedWorkTimer;
     64 
     65 private:
     66  // Only accessed by this class.
     67  RefPtr<DoWorkRunnable> mDoWorkEvent;
     68 };
     69 
     70 class MessagePumpForChildProcess final : public MessagePump {
     71 public:
     72  MessagePumpForChildProcess() : MessagePump(nullptr), mFirstRun(true) {}
     73 
     74  virtual void Run(base::MessagePump::Delegate* aDelegate) override;
     75 
     76 private:
     77  ~MessagePumpForChildProcess() = default;
     78 
     79  bool mFirstRun;
     80 };
     81 
     82 class MessagePumpForNonMainThreads final : public MessagePump {
     83 public:
     84  explicit MessagePumpForNonMainThreads(nsISerialEventTarget* aEventTarget)
     85      : MessagePump(aEventTarget) {}
     86 
     87  virtual void Run(base::MessagePump::Delegate* aDelegate) override;
     88 
     89 private:
     90  ~MessagePumpForNonMainThreads() = default;
     91 };
     92 
     93 #if defined(XP_WIN)
     94 // Extends the TYPE_UI message pump to process xpcom events.
     95 class MessagePumpForNonMainUIThreads final : public base::MessagePumpForUI,
     96                                             public nsIThreadObserver {
     97 public:
     98  NS_DECL_ISUPPORTS_INHERITED
     99  NS_DECL_NSITHREADOBSERVER
    100 
    101 public:
    102  explicit MessagePumpForNonMainUIThreads(nsISerialEventTarget* aEventTarget)
    103      : mInWait(false), mWaitLock("mInWait") {}
    104 
    105  // The main run loop for this thread.
    106  virtual void DoRunLoop() override;
    107 
    108  virtual nsISerialEventTarget* GetXPCOMThread() override {
    109    return nullptr;  // not sure what to do with this one
    110  }
    111 
    112 protected:
    113  void SetInWait() {
    114    MutexAutoLock lock(mWaitLock);
    115    mInWait = true;
    116  }
    117 
    118  void ClearInWait() {
    119    MutexAutoLock lock(mWaitLock);
    120    mInWait = false;
    121  }
    122 
    123  bool GetInWait() {
    124    MutexAutoLock lock(mWaitLock);
    125    return mInWait;
    126  }
    127 
    128 private:
    129  ~MessagePumpForNonMainUIThreads() {}
    130 
    131  bool mInWait MOZ_GUARDED_BY(mWaitLock);
    132  mozilla::Mutex mWaitLock;
    133 };
    134 #elif defined(XP_DARWIN)
    135 // Extends the CFRunLoopBase message pump to process xpcom events. Based on
    136 // MessagePumpNSRunLoop.
    137 class MessagePumpForNonMainUIThreads final
    138    : public base::MessagePumpCFRunLoopBase,
    139      public nsIThreadObserver {
    140 public:
    141  NS_DECL_ISUPPORTS_INHERITED
    142  NS_DECL_NSITHREADOBSERVER
    143 
    144 public:
    145  explicit MessagePumpForNonMainUIThreads(nsISerialEventTarget* aEventTarget);
    146 
    147  void DoRun(base::MessagePump::Delegate* aDelegate) override;
    148  void Quit() override;
    149 
    150  nsISerialEventTarget* GetXPCOMThread() override { return mEventTarget; }
    151 
    152 private:
    153  ~MessagePumpForNonMainUIThreads();
    154 
    155  nsISerialEventTarget* mEventTarget;
    156 
    157  // A source that doesn't do anything but provide something signalable
    158  // attached to the run loop.  This source will be signalled when Quit
    159  // is called, to cause the loop to wake up so that it can stop.
    160  CFRunLoopSourceRef quit_source_;
    161 
    162  // False after Quit is called.
    163  bool keep_running_;
    164 
    165  DISALLOW_COPY_AND_ASSIGN(MessagePumpForNonMainUIThreads);
    166 };
    167 #endif  // defined(XP_DARWIN)
    168 
    169 #if defined(MOZ_WIDGET_ANDROID)
    170 /*`
    171 * The MessagePumpForAndroidUI exists to enable IPDL in the Android UI thread.
    172 * The Android UI thread event loop is controlled by Android. This prevents
    173 * running an existing MessagePump implementation in the Android UI thread. In
    174 * order to enable IPDL on the Android UI thread it is necessary to have a
    175 * non-looping MessagePump. This class enables forwarding of nsIRunnables from
    176 * MessageLoop::PostTask_Helper to the registered nsIEventTarget with out the
    177 * need to control the event loop. The only member function that should be
    178 * invoked is GetXPCOMThread. All other member functions will invoke MOZ_CRASH
    179 */
    180 class MessagePumpForAndroidUI : public base::MessagePump {
    181 public:
    182  explicit MessagePumpForAndroidUI(nsISerialEventTarget* aEventTarget)
    183      : mEventTarget(aEventTarget) {}
    184 
    185  virtual void Run(Delegate* delegate);
    186  virtual void Quit();
    187  virtual void ScheduleWork();
    188  virtual void ScheduleDelayedWork(const base::TimeTicks& delayed_work_time);
    189  virtual nsISerialEventTarget* GetXPCOMThread() { return mEventTarget; }
    190 
    191 private:
    192  ~MessagePumpForAndroidUI() {}
    193  MessagePumpForAndroidUI() {}
    194 
    195  nsISerialEventTarget* mEventTarget;
    196 };
    197 #endif  // defined(MOZ_WIDGET_ANDROID)
    198 
    199 } /* namespace ipc */
    200 } /* namespace mozilla */
    201 
    202 #endif /* __IPC_GLUE_MESSAGEPUMP_H__ */