tor-browser

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

MessagePump_windows.cpp (2843B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=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 "MessagePump.h"
      8 
      9 using namespace mozilla::ipc;
     10 
     11 NS_IMPL_ADDREF_INHERITED(MessagePumpForNonMainUIThreads, MessagePump)
     12 NS_IMPL_RELEASE_INHERITED(MessagePumpForNonMainUIThreads, MessagePump)
     13 NS_IMPL_QUERY_INTERFACE(MessagePumpForNonMainUIThreads, nsIThreadObserver)
     14 
     15 #define CHECK_QUIT_STATE       \
     16  {                            \
     17    if (state_->should_quit) { \
     18      break;                   \
     19    }                          \
     20  }
     21 
     22 void MessagePumpForNonMainUIThreads::DoRunLoop() {
     23  MOZ_RELEASE_ASSERT(!NS_IsMainThread(),
     24                     "Use mozilla::ipc::MessagePump instead!");
     25 
     26  // If this is a chromium thread and no nsThread is associated
     27  // with it, this call will create a new nsThread.
     28  nsIThread* thread = NS_GetCurrentThread();
     29  MOZ_ASSERT(thread);
     30 
     31  // Set the main thread observer so we can wake up when
     32  // xpcom events need to get processed.
     33  nsCOMPtr<nsIThreadInternal> ti(do_QueryInterface(thread));
     34  MOZ_ASSERT(ti);
     35  ti->SetObserver(this);
     36 
     37  for (;;) {
     38    bool didWork = NS_ProcessNextEvent(thread, false);
     39 
     40    didWork |= ProcessNextWindowsMessage();
     41    CHECK_QUIT_STATE
     42 
     43    didWork |= state_->delegate->DoWork();
     44    CHECK_QUIT_STATE
     45 
     46    didWork |= state_->delegate->DoDelayedWork(&delayed_work_time_);
     47    if (didWork && delayed_work_time_.is_null()) {
     48      KillTimer(message_hwnd_, reinterpret_cast<UINT_PTR>(this));
     49    }
     50    CHECK_QUIT_STATE
     51 
     52    if (didWork) {
     53      continue;
     54    }
     55 
     56    DebugOnly<bool> didIdleWork = state_->delegate->DoIdleWork();
     57    MOZ_ASSERT(!didIdleWork);
     58    CHECK_QUIT_STATE
     59 
     60    SetInWait();
     61    bool hasWork = NS_HasPendingEvents(thread);
     62    if (didWork || hasWork) {
     63      ClearInWait();
     64      continue;
     65    }
     66    WaitForWork();  // Calls MsgWaitForMultipleObjectsEx(QS_ALLINPUT)
     67    ClearInWait();
     68  }
     69 
     70  ClearInWait();
     71 
     72  ti->SetObserver(nullptr);
     73 }
     74 
     75 NS_IMETHODIMP
     76 MessagePumpForNonMainUIThreads::OnDispatchedEvent() {
     77  // If our thread is sleeping in DoRunLoop's call to WaitForWork() and an
     78  // event posts to the nsIThread event queue - break our thread out of
     79  // chromium's WaitForWork.
     80  if (GetInWait()) {
     81    ScheduleWork();
     82  }
     83  return NS_OK;
     84 }
     85 
     86 NS_IMETHODIMP
     87 MessagePumpForNonMainUIThreads::OnProcessNextEvent(nsIThreadInternal* thread,
     88                                                   bool mayWait) {
     89  return NS_OK;
     90 }
     91 
     92 NS_IMETHODIMP
     93 MessagePumpForNonMainUIThreads::AfterProcessNextEvent(nsIThreadInternal* thread,
     94                                                      bool eventWasProcessed) {
     95  return NS_OK;
     96 }