tor-browser

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

GCLock.h (2673B)


      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 /*
      8 * GC-internal classes for acquiring and releasing the GC lock.
      9 */
     10 
     11 #ifndef gc_GCLock_h
     12 #define gc_GCLock_h
     13 
     14 #include "vm/Runtime.h"
     15 
     16 namespace js {
     17 
     18 /*
     19 * RAII class that takes the GC lock while it is live.
     20 *
     21 * Usually functions will pass const references of this class.  However
     22 * non-const references can be used to either temporarily release the lock by
     23 * use of AutoUnlockGC or to start background allocation when the lock is
     24 * released.
     25 */
     26 class MOZ_RAII AutoLockGC {
     27 public:
     28  explicit AutoLockGC(gc::GCRuntime* gc) : gc(gc) { lock(); }
     29  explicit AutoLockGC(JSRuntime* rt) : AutoLockGC(&rt->gc) {}
     30 
     31  ~AutoLockGC() { lockGuard_.reset(); }
     32 
     33  LockGuard<Mutex>& guard() { return lockGuard_.ref(); }
     34 
     35 protected:
     36  void lock() {
     37    MOZ_ASSERT(lockGuard_.isNothing());
     38    lockGuard_.emplace(gc->lock);
     39  }
     40 
     41  void unlock() {
     42    MOZ_ASSERT(lockGuard_.isSome());
     43    lockGuard_.reset();
     44  }
     45 
     46  gc::GCRuntime* const gc;
     47 
     48 private:
     49  mozilla::Maybe<LockGuard<Mutex>> lockGuard_;
     50 
     51  AutoLockGC(const AutoLockGC&) = delete;
     52  AutoLockGC& operator=(const AutoLockGC&) = delete;
     53 
     54  friend class UnlockGuard<AutoLockGC>;  // For lock/unlock.
     55 };
     56 
     57 /*
     58 * Same as AutoLockGC except it can optionally start a background chunk
     59 * allocation task when the lock is released.
     60 */
     61 class MOZ_RAII AutoLockGCBgAlloc : public AutoLockGC {
     62 public:
     63  explicit AutoLockGCBgAlloc(gc::GCRuntime* gc) : AutoLockGC(gc) {}
     64  explicit AutoLockGCBgAlloc(JSRuntime* rt) : AutoLockGCBgAlloc(&rt->gc) {}
     65 
     66  ~AutoLockGCBgAlloc() {
     67    unlock();
     68 
     69    /*
     70     * We have to do this after releasing the lock because it may acquire
     71     * the helper lock which could cause lock inversion if we still held
     72     * the GC lock.
     73     */
     74    if (startBgAlloc) {
     75      gc->startBackgroundAllocTaskIfIdle();
     76    }
     77  }
     78 
     79  /*
     80   * This can be used to start a background allocation task (if one isn't
     81   * already running) that allocates chunks and makes them available in the
     82   * free chunks list.  This happens after the lock is released in order to
     83   * avoid lock inversion.
     84   */
     85  void tryToStartBackgroundAllocation() { startBgAlloc = true; }
     86 
     87 private:
     88  // true if we should start a background chunk allocation task after the
     89  // lock is released.
     90  bool startBgAlloc = false;
     91 };
     92 
     93 using AutoUnlockGC = UnlockGuard<AutoLockGC>;
     94 
     95 }  // namespace js
     96 
     97 #endif /* gc_GCLock_h */