void IOBuf::decrementRefcount() noexcept {
  // Externally owned buffers don't have a SharedInfo object and aren't managed
  // by the reference count
  SharedInfo* info = sharedInfo();
  if (!info) {
    return;
  }

  // Avoid doing atomic decrement if the refcount is 1.
  // This is safe, because it means that we're the last reference and destroying
  // the object. Anything trying to copy it is already undefined behavior.
  if (info->refcount.load(std::memory_order_acquire) > 1) {
    // Decrement the refcount
    uint32_t newcnt = info->refcount.fetch_sub(1, std::memory_order_acq_rel);
    // Note that fetch_sub() returns the value before we decremented.
    // If it is 1, we were the only remaining user; if it is greater there are
    // still other users.
    if (newcnt > 1) {
      return;
    }
  }

  // save the useHeapFullStorage flag here since
  // freeExtBuffer can delete the sharedInfo()
  bool useHeapFullStorage = info->useHeapFullStorage;

  // We were the last user.  Free the buffer
  freeExtBuffer();

  // Free the SharedInfo if it was allocated separately.
  //
  // This is only used by takeOwnership().
  //
  // To avoid this special case handling in decrementRefcount(), we could have
  // takeOwnership() set a custom freeFn() that calls the user's free function
  // then frees the SharedInfo object.  (This would require that
  // takeOwnership() store the user's free function with its allocated
  // SharedInfo object.)  However, handling this specially with a flag seems
  // like it shouldn't be problematic.
  if (flags() & kFlagFreeSharedInfo) {
    delete info;
  } else {
    if (useHeapFullStorage) {
      SharedInfo::releaseStorage(info);
    }
  }
}
void IOBuf::decrementRefcount() noexcept {
   
   
  SharedInfo* info = sharedInfo();
  if (!info) {
    return;
  }

   
   
   
  if (info->refcount.load(std::memory_order_acquire) > 1) {
     
    uint32_t newcnt = info->refcount.fetch_sub(1, std::memory_order_acq_rel);
     
     
     
    if (newcnt > 1) {
      return;
    }
  }

   
   
  bool useHeapFullStorage = info->useHeapFullStorage;

   
  freeExtBuffer();

   
   
   
   
   
   
   
   
   
   
  if (flags() & kFlagFreeSharedInfo) {
    delete info;
  } else {
    if (useHeapFullStorage) {
      SharedInfo::releaseStorage(info);
    }
  }
}