tor-browser

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

APZThreadUtils.cpp (3670B)


      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 "APZThreadUtils.h"
      8 
      9 #include "mozilla/ClearOnShutdown.h"
     10 #include "mozilla/ProfilerRunnable.h"
     11 #include "mozilla/StaticMutex.h"
     12 
     13 #include "nsISerialEventTarget.h"
     14 #include "nsThreadUtils.h"
     15 #include "nsXULAppAPI.h"
     16 
     17 namespace mozilla {
     18 namespace layers {
     19 
     20 static bool sThreadAssertionsEnabled = true;
     21 static StaticRefPtr<nsISerialEventTarget> sControllerThread;
     22 static StaticMutex sControllerThreadMutex MOZ_UNANNOTATED;
     23 
     24 /*static*/
     25 void APZThreadUtils::SetThreadAssertionsEnabled(bool aEnabled) {
     26  StaticMutexAutoLock lock(sControllerThreadMutex);
     27  sThreadAssertionsEnabled = aEnabled;
     28 }
     29 
     30 /*static*/
     31 bool APZThreadUtils::GetThreadAssertionsEnabled() {
     32  StaticMutexAutoLock lock(sControllerThreadMutex);
     33  return sThreadAssertionsEnabled;
     34 }
     35 
     36 /*static*/
     37 void APZThreadUtils::SetControllerThread(nsISerialEventTarget* aThread) {
     38  // We must either be setting the initial controller thread, or removing it,
     39  // or re-using an existing controller thread.
     40  StaticMutexAutoLock lock(sControllerThreadMutex);
     41  MOZ_ASSERT(!sControllerThread || !aThread || sControllerThread == aThread);
     42  if (aThread != sControllerThread) {
     43    // This can only happen once, on startup.
     44    sControllerThread = aThread;
     45    ClearOnShutdown(&sControllerThread);
     46  }
     47 }
     48 
     49 /*static*/
     50 void APZThreadUtils::AssertOnControllerThread() {
     51 #if DEBUG
     52  if (!GetThreadAssertionsEnabled()) {
     53    return;
     54  }
     55  StaticMutexAutoLock lock(sControllerThreadMutex);
     56  MOZ_ASSERT(sControllerThread && sControllerThread->IsOnCurrentThread());
     57 #endif
     58 }
     59 
     60 /*static*/
     61 void APZThreadUtils::RunOnControllerThread(
     62    RefPtr<Runnable>&& aTask, nsIEventTarget::DispatchFlags flags) {
     63  RefPtr<nsISerialEventTarget> thread;
     64  {
     65    StaticMutexAutoLock lock(sControllerThreadMutex);
     66    thread = sControllerThread;
     67  }
     68  RefPtr<Runnable> task = std::move(aTask);
     69 
     70  if (!thread) {
     71    // Could happen on startup or if Shutdown() got called.
     72    NS_WARNING("Dropping task posted to controller thread");
     73    return;
     74  }
     75 
     76  if (thread->IsOnCurrentThread()) {
     77    AUTO_PROFILE_FOLLOWING_RUNNABLE(task);
     78    task->Run();
     79  } else {
     80    thread->Dispatch(task.forget(), flags);
     81  }
     82 }
     83 
     84 /*static*/
     85 already_AddRefed<nsISerialEventTarget> APZThreadUtils::GetControllerThread() {
     86  StaticMutexAutoLock lock(sControllerThreadMutex);
     87  return do_AddRef(sControllerThread);
     88 }
     89 
     90 /*static*/
     91 bool APZThreadUtils::IsControllerThread() {
     92  StaticMutexAutoLock lock(sControllerThreadMutex);
     93  return sControllerThread && sControllerThread->IsOnCurrentThread();
     94 }
     95 
     96 /*static*/
     97 bool APZThreadUtils::IsControllerThreadAlive() {
     98  StaticMutexAutoLock lock(sControllerThreadMutex);
     99  return !!sControllerThread;
    100 }
    101 
    102 /*static*/
    103 void APZThreadUtils::DelayedDispatch(already_AddRefed<Runnable> aRunnable,
    104                                     int aDelayMs) {
    105  MOZ_ASSERT(!XRE_IsContentProcess(),
    106             "ContentProcessController should only be used remotely.");
    107  RefPtr<nsISerialEventTarget> thread;
    108  {
    109    StaticMutexAutoLock lock(sControllerThreadMutex);
    110    thread = sControllerThread;
    111  }
    112  if (!thread) {
    113    // Could happen on startup
    114    NS_WARNING("Dropping task posted to controller thread");
    115    return;
    116  }
    117  if (aDelayMs) {
    118    thread->DelayedDispatch(std::move(aRunnable), aDelayMs);
    119  } else {
    120    thread->Dispatch(std::move(aRunnable));
    121  }
    122 }
    123 
    124 }  // namespace layers
    125 }  // namespace mozilla