diff options
author | Cy Schubert <cy@FreeBSD.org> | 2023-11-14 23:02:42 +0000 |
---|---|---|
committer | Cy Schubert <cy@FreeBSD.org> | 2023-11-14 23:02:42 +0000 |
commit | 5223d1d95fddcef6f9a36e264a5800bd907ade8b (patch) | |
tree | 818b1eba912c588e39058586485699385c3179fe /buffer.c | |
parent | cbc620a473ce23d882ba3e9f91ec0c6c12dcd239 (diff) |
libevent: Import libevent 2.1.12vendor/libevent
Diffstat (limited to 'buffer.c')
-rw-r--r-- | buffer.c | 50 |
1 files changed, 35 insertions, 15 deletions
@@ -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 * |