xfree(ptr);
}
+dwrite_q::dwrite_q(const size_t aSize, char * const aBuffer, FREE * const aFree):
+ buf(aBuffer),
+ capacity(aSize),
+ free_func(aFree)
+{
+ assert(buf || !free_func);
+ if (!buf) {
+ buf = static_cast<char *>(xmalloc(aSize));
+ free_func = cxx_xfree; // dwrite_q buffer xfree()
+ } else {
+ len = aSize;
+ }
+}
+
+dwrite_q::~dwrite_q()
+{
+ if (free_func)
+ free_func(buf);
+}
+
/*
* opens a disk file specified by 'path'. This function always
* blocks! There is no callback.
*/
if (fdd->write_q != nullptr && fdd->write_q->next != nullptr) {
- int len = 0;
+ size_t wantCapacity = 0;
for (dwrite_q *q = fdd->write_q; q != nullptr; q = q->next)
- len += q->len - q->buf_offset;
-
- dwrite_q *wq = (dwrite_q *)memAllocate(MEM_DWRITE_Q);
-
- wq->buf = (char *)xmalloc(len);
-
- wq->len = 0;
-
- wq->buf_offset = 0;
+ wantCapacity += q->len - q->buf_offset; // XXX: might overflow
- wq->next = nullptr;
-
- wq->free_func = cxx_xfree;
-
- while (fdd->write_q != nullptr) {
- dwrite_q *q = fdd->write_q;
-
- len = q->len - q->buf_offset;
+ const auto wq = new dwrite_q(wantCapacity);
+ while (const auto q = fdd->write_q) {
+ const auto len = q->len - q->buf_offset;
memcpy(wq->buf + wq->len, q->buf + q->buf_offset, len);
wq->len += len;
fdd->write_q = q->next;
-
- if (q->free_func)
- q->free_func(q->buf);
-
- memFree(q, MEM_DWRITE_Q);
+ delete q;
};
fdd->write_q_tail = wq;
fde *F = &fd_table[fd];
_fde_disk *fdd = &F->disk;
- dwrite_q *q = fdd->write_q;
int status = DISK_OK;
bool do_close;
- if (nullptr == q)
+ if (!fdd->write_q)
return;
debugs(6, 3, "diskHandleWrite: FD " << fd);
* repeated write failures for the same FD because of
* the queued data.
*/
- do {
+ while (const auto q = fdd->write_q) {
fdd->write_q = q->next;
-
- if (q->free_func)
- q->free_func(q->buf);
-
- if (q) {
- memFree(q, MEM_DWRITE_Q);
- q = nullptr;
- }
- } while ((q = fdd->write_q));
+ delete q;
+ }
}
len = 0;
}
- if (q != nullptr) {
+ if (const auto q = fdd->write_q) {
/* q might become NULL from write failure above */
q->buf_offset += len;
if (q->buf_offset == q->len) {
/* complete write */
fdd->write_q = q->next;
-
- if (q->free_func)
- q->free_func(q->buf);
-
- if (q) {
- memFree(q, MEM_DWRITE_Q);
- q = nullptr;
- }
+ delete q;
}
}
void *handle_data,
FREE * free_func)
{
- dwrite_q *wq = nullptr;
fde *F = &fd_table[fd];
assert(fd >= 0);
assert(F->flags.open);
/* if we got here. Caller is eligible to write. */
- wq = (dwrite_q *)memAllocate(MEM_DWRITE_Q);
+ const auto wq = new dwrite_q(len, static_cast<char *>(const_cast<void *>(ptr_to_buf)), free_func);
wq->file_offset = file_offset;
- wq->buf = (char *)ptr_to_buf;
- wq->len = len;
- wq->buf_offset = 0;
- wq->next = nullptr;
- wq->free_func = free_func;
if (!F->disk.wrt_handle_data) {
F->disk.wrt_handle = handle;
void *client_data;
};
-// POD
class dwrite_q
{
+ MEMPROXY_CLASS(dwrite_q);
public:
- off_t file_offset;
- char *buf;
- size_t len;
- size_t buf_offset;
- dwrite_q *next;
- FREE *free_func;
+ dwrite_q(const size_t wantCapacity) : dwrite_q(wantCapacity, nullptr, nullptr) {}
+ dwrite_q(size_t, char *, FREE *);
+ dwrite_q(dwrite_q &&) = delete; // no copying or moving of any kind
+ ~dwrite_q();
+
+ off_t file_offset = 0;
+ char *buf = nullptr;
+ size_t len = 0; ///< length of content in buf
+ size_t buf_offset = 0;
+ dwrite_q *next = nullptr;
+
+private:
+ size_t capacity = 0; ///< allocation size of buf
+ /// when set, gets called upon object destruction to free buf
+ FREE *free_func = nullptr;
};
int file_open(const char *path, int mode);
memDataInit(MEM_64K_BUF, "64K Buffer", 65536, 10, false);
// TODO: Carefully stop zeroing these objects memory and drop the doZero parameter
memDataInit(MEM_DREAD_CTRL, "dread_ctrl", sizeof(dread_ctrl), 0, true);
- memDataInit(MEM_DWRITE_Q, "dwrite_q", sizeof(dwrite_q), 0, true);
memDataInit(MEM_MD5_DIGEST, "MD5 digest", SQUID_MD5_DIGEST_LENGTH, 0, true);
GetPool(MEM_MD5_DIGEST)->setChunkSize(512 * 1024);