예제 #1
0
파일: IOBuf.cpp 프로젝트: charsyam/folly
void IOBuf::unshareOneSlow() {
  // Allocate a new buffer for the data
  uint8_t* buf;
  SharedInfo* sharedInfo;
  uint64_t actualCapacity;
  allocExtBuffer(capacity_, &buf, &sharedInfo, &actualCapacity);

  // Copy the data
  // Maintain the same amount of headroom.  Since we maintained the same
  // minimum capacity we also maintain at least the same amount of tailroom.
  uint64_t headlen = headroom();
  if (length_ > 0) {
    assert(data_ != nullptr);
    memcpy(buf + headlen, data_, length_);
  }

  // Release our reference on the old buffer
  decrementRefcount();
  // Make sure kFlagMaybeShared and kFlagFreeSharedInfo are all cleared.
  setFlagsAndSharedInfo(0, sharedInfo);

  // Update the buffer pointers to point to the new buffer
  data_ = buf + headlen;
  buf_ = buf;
}
예제 #2
0
파일: IOBuf.cpp 프로젝트: charsyam/folly
IOBuf::~IOBuf() {
  // Destroying an IOBuf destroys the entire chain.
  // Users of IOBuf should only explicitly delete the head of any chain.
  // The other elements in the chain will be automatically destroyed.
  while (next_ != this) {
    // Since unlink() returns unique_ptr() and we don't store it,
    // it will automatically delete the unlinked element.
    (void)next_->unlink();
  }

  decrementRefcount();
}
예제 #3
0
파일: IOBuf.cpp 프로젝트: JingangLi/folly
void IOBuf::coalesceAndReallocate(size_t newHeadroom,
                                  size_t newLength,
                                  IOBuf* end,
                                  size_t newTailroom) {
  uint64_t newCapacity = newLength + newHeadroom + newTailroom;
  if (newCapacity > UINT32_MAX) {
    throw std::overflow_error("IOBuf chain too large to coalesce");
  }

  // Allocate space for the coalesced buffer.
  // We always convert to an external buffer, even if we happened to be an
  // internal buffer before.
  uint8_t* newBuf;
  SharedInfo* newInfo;
  uint32_t actualCapacity;
  allocExtBuffer(newCapacity, &newBuf, &newInfo, &actualCapacity);

  // Copy the data into the new buffer
  uint8_t* newData = newBuf + newHeadroom;
  uint8_t* p = newData;
  IOBuf* current = this;
  size_t remaining = newLength;
  do {
    assert(current->length_ <= remaining);
    remaining -= current->length_;
    memcpy(p, current->data_, current->length_);
    p += current->length_;
    current = current->next_;
  } while (current != end);
  assert(remaining == 0);

  // Point at the new buffer
  decrementRefcount();

  // Make sure kFlagUserOwned, kFlagMaybeShared, and kFlagFreeSharedInfo
  // are all cleared.
  flags_ = 0;

  capacity_ = actualCapacity;
  type_ = kExtAllocated;
  buf_ = newBuf;
  sharedInfo_ = newInfo;
  data_ = newData;
  length_ = newLength;

  // Separate from the rest of our chain.
  // Since we don't store the unique_ptr returned by separateChain(),
  // this will immediately delete the returned subchain.
  if (isChained()) {
    (void)separateChain(next_, current->prev_);
  }
}
예제 #4
0
파일: IOBuf.cpp 프로젝트: charsyam/folly
void IOBuf::coalesceAndReallocate(size_t newHeadroom,
                                  size_t newLength,
                                  IOBuf* end,
                                  size_t newTailroom) {
  uint64_t newCapacity = newLength + newHeadroom + newTailroom;

  // Allocate space for the coalesced buffer.
  // We always convert to an external buffer, even if we happened to be an
  // internal buffer before.
  uint8_t* newBuf;
  SharedInfo* newInfo;
  uint64_t actualCapacity;
  allocExtBuffer(newCapacity, &newBuf, &newInfo, &actualCapacity);

  // Copy the data into the new buffer
  uint8_t* newData = newBuf + newHeadroom;
  uint8_t* p = newData;
  IOBuf* current = this;
  size_t remaining = newLength;
  do {
    if (current->length_ > 0) {
      assert(current->length_ <= remaining);
      assert(current->data_ != nullptr);
      remaining -= current->length_;
      memcpy(p, current->data_, current->length_);
      p += current->length_;
    }
    current = current->next_;
  } while (current != end);
  assert(remaining == 0);

  // Point at the new buffer
  decrementRefcount();

  // Make sure kFlagMaybeShared and kFlagFreeSharedInfo are all cleared.
  setFlagsAndSharedInfo(0, newInfo);

  capacity_ = actualCapacity;
  buf_ = newBuf;
  data_ = newData;
  length_ = newLength;

  // Separate from the rest of our chain.
  // Since we don't store the unique_ptr returned by separateChain(),
  // this will immediately delete the returned subchain.
  if (isChained()) {
    (void)separateChain(next_, current->prev_);
  }
}
예제 #5
0
파일: IOBuf.cpp 프로젝트: JingangLi/folly
IOBuf& IOBuf::operator=(IOBuf&& other) noexcept {
  // If we are part of a chain, delete the rest of the chain.
  while (next_ != this) {
    // Since unlink() returns unique_ptr() and we don't store it,
    // it will automatically delete the unlinked element.
    (void)next_->unlink();
  }

  // Decrement our refcount on the current buffer
  decrementRefcount();

  // Take ownership of the other buffer's data
  data_ = other.data_;
  buf_ = other.buf_;
  length_ = other.length_;
  capacity_ = other.capacity_;
  flags_ = other.flags_;
  type_ = other.type_;
  sharedInfo_ = other.sharedInfo_;
  // Reset other so it is a clean state to be destroyed.
  other.data_ = nullptr;
  other.buf_ = nullptr;
  other.length_ = 0;
  other.capacity_ = 0;
  other.flags_ = kFlagUserOwned;
  other.type_ = kExtUserOwned;
  other.sharedInfo_ = nullptr;

  // If other was part of the chain, assume ownership of the rest of its chain.
  // (It's only valid to perform move assignment on the head of a chain.)
  if (other.next_ != &other) {
    next_ = other.next_;
    next_->prev_ = this;
    other.next_ = &other;

    prev_ = other.prev_;
    prev_->next_ = this;
    other.prev_ = &other;
  }

  // Sanity check to make sure that other is in a valid state to be destroyed.
  DCHECK_EQ(other.prev_, &other);
  DCHECK_EQ(other.next_, &other);
  DCHECK(other.flags_ & kFlagUserOwned);

  return *this;
}
예제 #6
0
파일: IOBuf.cpp 프로젝트: JingangLi/folly
void IOBuf::unshareOneSlow() {
  // Allocate a new buffer for the data
  uint8_t* buf;
  SharedInfo* sharedInfo;
  uint32_t actualCapacity;
  allocExtBuffer(capacity_, &buf, &sharedInfo, &actualCapacity);

  // Copy the data
  // Maintain the same amount of headroom.  Since we maintained the same
  // minimum capacity we also maintain at least the same amount of tailroom.
  uint32_t headlen = headroom();
  memcpy(buf + headlen, data_, length_);

  // Release our reference on the old buffer
  decrementRefcount();
  // Make sure kFlagUserOwned, kFlagMaybeShared, and kFlagFreeSharedInfo
  // are all cleared.
  flags_ = 0;

  // Update the buffer pointers to point to the new buffer
  data_ = buf + headlen;
  buf_ = buf;
  sharedInfo_ = sharedInfo;
}
void ResourceCache::decrementRefcount(const Res_png_9patch* patchResource) {
    decrementRefcount((void*) patchResource);
}
void ResourceCache::decrementRefcount(const SkPath* pathResource) {
    decrementRefcount((void*) pathResource);
}
void ResourceCache::decrementRefcount(const SkBitmap* bitmapResource) {
    decrementRefcount((void*) bitmapResource);
}
void ResourceCache::decrementRefcount(Layer* layerResource) {
    decrementRefcount((void*) layerResource);
}
void ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) {
    SkSafeUnref(filterResource->getSkColorFilter());
    decrementRefcount((void*) filterResource);
}
void ResourceCache::decrementRefcount(SkiaShader* shaderResource) {
    SkSafeUnref(shaderResource->getSkShader());
    decrementRefcount((void*) shaderResource);
}
void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
    bitmapResource->pixelRef()->globalUnref();
    SkSafeUnref(bitmapResource->getColorTable());
    decrementRefcount((void*) bitmapResource);
}