aboutsummaryrefslogtreecommitdiff
path: root/buffer.c
diff options
context:
space:
mode:
authorCy Schubert <cy@FreeBSD.org>2023-11-14 23:02:42 +0000
committerCy Schubert <cy@FreeBSD.org>2023-11-14 23:02:42 +0000
commit5223d1d95fddcef6f9a36e264a5800bd907ade8b (patch)
tree818b1eba912c588e39058586485699385c3179fe /buffer.c
parentcbc620a473ce23d882ba3e9f91ec0c6c12dcd239 (diff)
libevent: Import libevent 2.1.12vendor/libevent
Diffstat (limited to 'buffer.c')
-rw-r--r--buffer.c50
1 files changed, 35 insertions, 15 deletions
diff --git a/buffer.c b/buffer.c
index b7e3a69f4b20..3524b3504d43 100644
--- a/buffer.c
+++ b/buffer.c
@@ -95,6 +95,7 @@
#include "evthread-internal.h"
#include "evbuffer-internal.h"
#include "bufferevent-internal.h"
+#include "event-internal.h"
/* some systems do not have MAP_FAILED */
#ifndef MAP_FAILED
@@ -522,8 +523,8 @@ evbuffer_invoke_callbacks_(struct evbuffer *buffer)
evbuffer_incref_and_lock_(buffer);
if (buffer->parent)
bufferevent_incref_(buffer->parent);
+ EVBUFFER_UNLOCK(buffer);
}
- EVBUFFER_UNLOCK(buffer);
}
evbuffer_run_callbacks(buffer, 0);
@@ -703,13 +704,17 @@ static int
advance_last_with_data(struct evbuffer *buf)
{
int n = 0;
+ struct evbuffer_chain **chainp = buf->last_with_datap;
+
ASSERT_EVBUFFER_LOCKED(buf);
- if (!*buf->last_with_datap)
+ if (!*chainp)
return 0;
- while ((*buf->last_with_datap)->next && (*buf->last_with_datap)->next->off) {
- buf->last_with_datap = &(*buf->last_with_datap)->next;
+ while ((*chainp)->next) {
+ chainp = &(*chainp)->next;
+ if ((*chainp)->off)
+ buf->last_with_datap = chainp;
++n;
}
return n;
@@ -1146,7 +1151,7 @@ evbuffer_drain(struct evbuffer *buf, size_t len)
}
buf->first = chain;
- EVUTIL_ASSERT(chain && remaining <= chain->off);
+ EVUTIL_ASSERT(remaining <= chain->off);
chain->misalign += remaining;
chain->off -= remaining;
}
@@ -1298,7 +1303,7 @@ evbuffer_remove_buffer(struct evbuffer *src, struct evbuffer *dst,
chain = chain->next;
}
- if (nread) {
+ if (chain != src->first) {
/* we can remove the chain */
struct evbuffer_chain **chp;
chp = evbuffer_free_trailing_empty_chains(dst);
@@ -1416,9 +1421,11 @@ evbuffer_pullup(struct evbuffer *buf, ev_ssize_t size)
for (; chain != NULL && (size_t)size >= chain->off; chain = next) {
next = chain->next;
- memcpy(buffer, chain->buffer + chain->misalign, chain->off);
- size -= chain->off;
- buffer += chain->off;
+ if (chain->buffer) {
+ memcpy(buffer, chain->buffer + chain->misalign, chain->off);
+ size -= chain->off;
+ buffer += chain->off;
+ }
if (chain == last_with_data)
removed_last_with_data = 1;
if (&chain->next == buf->last_with_datap)
@@ -1534,11 +1541,11 @@ evbuffer_find_eol_char(struct evbuffer_ptr *it)
return (-1);
}
-static inline int
+static inline size_t
evbuffer_strspn(
struct evbuffer_ptr *ptr, const char *chrset)
{
- int count = 0;
+ size_t count = 0;
struct evbuffer_chain *chain = ptr->internal_.chain;
size_t i = ptr->internal_.pos_in_chain;
@@ -1824,6 +1831,10 @@ evbuffer_prepend(struct evbuffer *buf, const void *data, size_t datlen)
EVBUFFER_LOCK(buf);
+ if (datlen == 0) {
+ result = 0;
+ goto done;
+ }
if (buf->freeze_start) {
goto done;
}
@@ -1877,7 +1888,7 @@ evbuffer_prepend(struct evbuffer *buf, const void *data, size_t datlen)
if ((tmp = evbuffer_chain_new(datlen)) == NULL)
goto done;
buf->first = tmp;
- if (buf->last_with_datap == &buf->first)
+ if (buf->last_with_datap == &buf->first && chain->off)
buf->last_with_datap = &tmp->next;
tmp->next = chain;
@@ -2227,11 +2238,13 @@ evbuffer_read_setup_vecs_(struct evbuffer *buf, ev_ssize_t howmuch,
so_far = 0;
/* Let firstchain be the first chain with any space on it */
firstchainp = buf->last_with_datap;
+ EVUTIL_ASSERT(*firstchainp);
if (CHAIN_SPACE_LEN(*firstchainp) == 0) {
firstchainp = &(*firstchainp)->next;
}
chain = *firstchainp;
+ EVUTIL_ASSERT(chain);
for (i = 0; i < n_vecs_avail && so_far < (size_t)howmuch; ++i) {
size_t avail = (size_t) CHAIN_SPACE_LEN(chain);
if (avail > (howmuch - so_far) && exact)
@@ -2465,7 +2478,7 @@ evbuffer_write_sendfile(struct evbuffer *buffer, evutil_socket_t dest_fd,
ev_off_t len = chain->off;
#elif defined(SENDFILE_IS_LINUX) || defined(SENDFILE_IS_SOLARIS)
ev_ssize_t res;
- ev_off_t offset = chain->misalign;
+ off_t offset = chain->misalign;
#endif
ASSERT_EVBUFFER_LOCKED(buffer);
@@ -3198,7 +3211,6 @@ evbuffer_add_file_segment(struct evbuffer *buf,
}
}
}
- ++seg->refcnt;
EVLOCK_UNLOCK(seg->lock, 0);
if (buf->freeze_end)
@@ -3262,6 +3274,9 @@ evbuffer_add_file_segment(struct evbuffer *buf,
chain->off = length;
}
+ EVLOCK_LOCK(seg->lock, 0);
+ ++seg->refcnt;
+ EVLOCK_UNLOCK(seg->lock, 0);
extra->segment = seg;
buf->n_add_for_cb += length;
evbuffer_chain_insert(buf, chain);
@@ -3293,7 +3308,7 @@ evbuffer_add_file(struct evbuffer *buf, int fd, ev_off_t offset, ev_off_t length
return r;
}
-void
+int
evbuffer_setcb(struct evbuffer *buffer, evbuffer_cb cb, void *cbarg)
{
EVBUFFER_LOCK(buffer);
@@ -3304,10 +3319,15 @@ evbuffer_setcb(struct evbuffer *buffer, evbuffer_cb cb, void *cbarg)
if (cb) {
struct evbuffer_cb_entry *ent =
evbuffer_add_cb(buffer, NULL, cbarg);
+ if (!ent) {
+ EVBUFFER_UNLOCK(buffer);
+ return -1;
+ }
ent->cb.cb_obsolete = cb;
ent->flags |= EVBUFFER_CB_OBSOLETE;
}
EVBUFFER_UNLOCK(buffer);
+ return 0;
}
struct evbuffer_cb_entry *