void IOBuf::freeExtBuffer() noexcept {
  SharedInfo* info = sharedInfo();
  DCHECK(info);

  // save the observerListHead
  // since the SharedInfo can be freed
  auto observerListHead = info->observerListHead;
  info->observerListHead = nullptr;

  if (info->freeFn) {
    info->freeFn(buf_, info->userData);
  } else {
    // this will invoke free if info->userData is 0
    size_t size = reinterpret_cast<size_t>(info->userData);
    if (size) {
      if (io_buf_free_cb) {
        io_buf_free_cb(buf_, size);
      }
      folly::sizedFree(buf_, size);
    } else {
      free(buf_);
    }
  }
  SharedInfo::invokeAndDeleteEachObserver(
      observerListHead, [](auto& entry) { entry.afterFreeExtBuffer(); });

  if (kIsMobile) {
    buf_ = nullptr;
  }
}
void IOBuf::freeExtBuffer() noexcept {
  SharedInfo* info = sharedInfo();
  DCHECK(info);

   
   
  auto observerListHead = info->observerListHead;
  info->observerListHead = nullptr;

  if (info->freeFn) {
    info->freeFn(buf_, info->userData);
  } else {
     
    size_t size = reinterpret_cast<size_t>(info->userData);
    if (size) {
      if (io_buf_free_cb) {
        io_buf_free_cb(buf_, size);
      }
      folly::sizedFree(buf_, size);
    } else {
      free(buf_);
    }
  }
  SharedInfo::invokeAndDeleteEachObserver(
      observerListHead, [](auto& entry) { entry.afterFreeExtBuffer(); });

  if (kIsMobile) {
    buf_ = nullptr;
  }
}