tor-browser

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

RefCountedShmem.cpp (2343B)


      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 "RefCountedShmem.h"
      8 
      9 #include "mozilla/Atomics.h"
     10 #include "mozilla/ipc/ProtocolUtils.h"
     11 #include "mozilla/layers/WebRenderMessages.h"
     12 
     13 #define SHM_REFCOUNT_HEADER_SIZE 16
     14 
     15 namespace mozilla {
     16 namespace layers {
     17 
     18 uint8_t* RefCountedShm::GetBytes(const RefCountedShmem& aShm) {
     19  uint8_t* data = aShm.buffer().get<uint8_t>();
     20  if (!data) {
     21    return nullptr;
     22  }
     23  return data + SHM_REFCOUNT_HEADER_SIZE;
     24 }
     25 
     26 size_t RefCountedShm::GetSize(const RefCountedShmem& aShm) {
     27  if (!IsValid(aShm)) {
     28    return 0;
     29  }
     30  size_t totalSize = aShm.buffer().Size<uint8_t>();
     31  if (totalSize < SHM_REFCOUNT_HEADER_SIZE) {
     32    return 0;
     33  }
     34 
     35  return totalSize - SHM_REFCOUNT_HEADER_SIZE;
     36 }
     37 
     38 bool RefCountedShm::IsValid(const RefCountedShmem& aShm) {
     39  return aShm.buffer().IsWritable() &&
     40         aShm.buffer().Size<uint8_t>() > SHM_REFCOUNT_HEADER_SIZE;
     41 }
     42 
     43 int32_t RefCountedShm::GetReferenceCount(const RefCountedShmem& aShm) {
     44  if (!IsValid(aShm)) {
     45    return 0;
     46  }
     47 
     48  return *aShm.buffer().get<Atomic<int32_t>>();
     49 }
     50 
     51 int32_t RefCountedShm::AddRef(const RefCountedShmem& aShm) {
     52  if (!IsValid(aShm)) {
     53    return 0;
     54  }
     55 
     56  auto* counter = aShm.buffer().get<Atomic<int32_t>>();
     57  if (counter) {
     58    return (*counter)++;
     59  }
     60  return 0;
     61 }
     62 
     63 int32_t RefCountedShm::Release(const RefCountedShmem& aShm) {
     64  if (!IsValid(aShm)) {
     65    return 0;
     66  }
     67 
     68  auto* counter = aShm.buffer().get<Atomic<int32_t>>();
     69  if (counter) {
     70    return --(*counter);
     71  }
     72 
     73  return 0;
     74 }
     75 
     76 bool RefCountedShm::Alloc(mozilla::ipc::IProtocol* aAllocator, size_t aSize,
     77                          RefCountedShmem& aShm) {
     78  MOZ_ASSERT(!IsValid(aShm));
     79  auto size = aSize + SHM_REFCOUNT_HEADER_SIZE;
     80  if (!aAllocator->AllocUnsafeShmem(size, &aShm.buffer())) {
     81    return false;
     82  }
     83  return true;
     84 }
     85 
     86 void RefCountedShm::Dealloc(mozilla::ipc::IProtocol* aAllocator,
     87                            RefCountedShmem& aShm) {
     88  aAllocator->DeallocShmem(aShm.buffer());
     89  aShm.buffer() = ipc::Shmem();
     90 }
     91 
     92 }  // namespace layers
     93 }  // namespace mozilla