tor-browser

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

SharedBuffer.h (3707B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #ifndef MOZILLA_SHAREDBUFFER_H_
      7 #define MOZILLA_SHAREDBUFFER_H_
      8 
      9 #include "mozilla/CheckedInt.h"
     10 #include "mozilla/MemoryReporting.h"
     11 #include "mozilla/mozalloc.h"
     12 #include "nsISupportsImpl.h"
     13 
     14 namespace mozilla {
     15 
     16 class AudioBlockBuffer;
     17 class ThreadSharedFloatArrayBufferList;
     18 
     19 /**
     20 * Base class for objects with a thread-safe refcount and a virtual
     21 * destructor.
     22 */
     23 class ThreadSharedObject {
     24 public:
     25  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ThreadSharedObject)
     26 
     27  bool IsShared() { return mRefCnt.get() > 1; }
     28 
     29  virtual AudioBlockBuffer* AsAudioBlockBuffer() { return nullptr; };
     30  virtual ThreadSharedFloatArrayBufferList*
     31  AsThreadSharedFloatArrayBufferList() {
     32    return nullptr;
     33  };
     34 
     35  virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
     36    return 0;
     37  }
     38 
     39  virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
     40    return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
     41  }
     42 
     43 protected:
     44  // Protected destructor, to discourage deletion outside of Release():
     45  virtual ~ThreadSharedObject() = default;
     46 };
     47 
     48 /**
     49 * Heap-allocated chunk of arbitrary data with threadsafe refcounting.
     50 * Typically you would allocate one of these, fill it in, and then treat it as
     51 * immutable while it's shared.
     52 * This only guarantees 4-byte alignment of the data. For alignment we simply
     53 * assume that the memory from malloc is at least 4-byte aligned and the
     54 * refcount's size is large enough that SharedBuffer's size is divisible by 4.
     55 */
     56 class SharedBuffer : public ThreadSharedObject {
     57 public:
     58  void* Data() { return this + 1; }
     59 
     60  // Ensure that the caller has a CheckedInt.  We have to take one by
     61  // non-const reference to do that, because if we take one by const
     62  // reference or value or rvalue reference the implicit constructor on
     63  // CheckedInt will helpfully synthesize one for us at the callsite
     64  // even if the caller passes a raw size_t.
     65  static already_AddRefed<SharedBuffer> Create(CheckedInt<size_t>& aSize,
     66                                               const fallible_t&) {
     67    CheckedInt<size_t> allocSize = AllocSize(aSize, fallible);
     68    if (!allocSize.isValid()) {
     69      return nullptr;
     70    }
     71    void* m = operator new(allocSize.value(), fallible);
     72    if (!m) {
     73      return nullptr;
     74    }
     75    RefPtr<SharedBuffer> p = new (m) SharedBuffer();
     76    return p.forget();
     77  }
     78 
     79  static already_AddRefed<SharedBuffer> Create(CheckedInt<size_t>& aSize) {
     80    void* m = operator new(AllocSize(aSize));
     81    RefPtr<SharedBuffer> p = new (m) SharedBuffer();
     82    return p.forget();
     83  }
     84 
     85  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override {
     86    return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
     87  }
     88 
     89 private:
     90  static CheckedInt<size_t> AllocSize(CheckedInt<size_t> aDataSize,
     91                                      const fallible_t&) {
     92    CheckedInt<size_t> size = sizeof(SharedBuffer);
     93    size += aDataSize;
     94    return size;
     95  }
     96 
     97  static size_t AllocSize(CheckedInt<size_t> aDataSize) {
     98    CheckedInt<size_t> size = AllocSize(aDataSize, fallible);
     99    if (!size.isValid()) {
    100      MOZ_CRASH();
    101    }
    102    return size.value();
    103  }
    104 
    105  SharedBuffer() {
    106    NS_ASSERTION(
    107        (reinterpret_cast<char*>(this + 1) - reinterpret_cast<char*>(this)) %
    108                4 ==
    109            0,
    110        "SharedBuffers should be at least 4-byte aligned");
    111  }
    112 };
    113 
    114 }  // namespace mozilla
    115 
    116 #endif /* MOZILLA_SHAREDBUFFER_H_ */