IOBuf::IOBuf(TakeOwnershipOp, void* buf, uint64_t capacity, uint64_t length, FreeFunction freeFn, void* userData, bool freeOnError) : next_(this), prev_(this), data_(static_cast<uint8_t*>(buf)), buf_(static_cast<uint8_t*>(buf)), length_(length), capacity_(capacity), flagsAndSharedInfo_(packFlagsAndSharedInfo(kFlagFreeSharedInfo, nullptr)) { try { setSharedInfo(new SharedInfo(freeFn, userData)); } catch (...) { takeOwnershipError(freeOnError, buf, freeFn, userData); throw; } }
IOBuf::IOBuf(TakeOwnershipOp, void* buf, uint32_t capacity, uint32_t length, FreeFunction freeFn, void* userData, bool freeOnError) : next_(this), prev_(this), data_(static_cast<uint8_t*>(buf)), buf_(static_cast<uint8_t*>(buf)), length_(length), capacity_(capacity), flags_(kFlagFreeSharedInfo), type_(kExtUserSupplied) { try { sharedInfo_ = new SharedInfo(freeFn, userData); } catch (...) { takeOwnershipError(freeOnError, buf, freeFn, userData); throw; } }
unique_ptr<IOBuf> IOBuf::takeOwnership(void* buf, uint64_t capacity, uint64_t length, FreeFunction freeFn, void* userData, bool freeOnError) { try { // TODO: We could allocate the IOBuf object and SharedInfo all in a single // memory allocation. We could use the existing HeapStorage class, and // define a new kSharedInfoInUse flag. We could change our code to call // releaseStorage(kFlagFreeSharedInfo) when this kFlagFreeSharedInfo, // rather than directly calling delete. // // Note that we always pass freeOnError as false to the constructor. // If the constructor throws we'll handle it below. (We have to handle // allocation failures from make_unique too.) return make_unique<IOBuf>(TAKE_OWNERSHIP, buf, capacity, length, freeFn, userData, false); } catch (...) { takeOwnershipError(freeOnError, buf, freeFn, userData); throw; } }