evbuffer_pullup() returns NULL if you try to pull up more bytes than
are there. But evbuffer_write_atmost would sometimes ask for more
bytes to be pulled up than it had, get a NULL, and fail.
If the first chunk of a buffer is empty, and we're told to prepend to
the buffer, we should be willing to use the entire first chunk.
Instead, we were dependent on the value of chunk->misalign.
This constant decides the smallest (and typical) size of each evbuffer
chain. Since this number includes sizeof(evbuffer_chain) overhead,
the old value (256) was just too low: on 64-bit platforms, it would
spend nearly 20% of the allocations on overhead. The new values mean
that we'll be spending closer to 5% of evbuffer allocations on overhead.
It would be nice to get this number even lower if we can.
Previously, every call to min_heap_shift_down_() would invoke
min_heap_shift_up_() at the end. This used to be necessary in the
first version of the minheap code, since min_heap_erase() would call
min_heap_shift_down_() unconditionally. But when patch 8b7a3b36763
from Marko Kreen fixed min_heap_erase() to be more sensible, we left
the weird behavior of min_heap_shift_down_() in place.
Fortunately, "cui" noticed this and reported it on Niels's blog.
On 64-bit windows, configure actually _finds_ select when it tests for
it, and due to the ordering of the io implementations in event.c it is
chosen over the win32select implementation.
This modification skips the test for select on win32 (we don't want
that anyway, because Windows has its own), causing my windows box to
get the win32select implementation.
(edited by Nick)
Calling event_base_loop on a base from inside a callback invoked by
that same base, or from two threads at once, has long been a way to
get exceedingly hard-to-diagnose errors. This patch adds code to
detect such reentrant invocatinos, and exit quickly with a warning
that should explain what went wrong.
This is mainly intended to ensure that we don't get hung up on
the 64-handle limit that lots of O(n) Windows functions (but FWICT
not select) like to enforce.
We were saying
mm_free(bufev - bufev->be_ops->mem_offset);
when we should have said
mm_free(((char*)bufev) - bufev->be_ops->mem_offset);
In other words, if mem_offset had ever been nonzero, then instead of
backing up mem_offset bytes to find the thing we were supposed to free, we
would have backed up mem_offset*sizeof(struct bufferevent) bytes, and freed
something completely crazy.
Spotted thanks to a conversation with Jardel Weyrich
It looks like when we moved from one big inflight-requests list to an
n-heads structure, we didn't make evdns_base_free() free the array of
heads. This patch should fix that.
Found with valgrind
On Linux, we use only one fd to do main-thread signaling (since we have
eventfd()), so we don't need to close th_notify_fd[1] as we would if we were
using a socketpair.
We were using the same bufferevent as the child of two filtering parents,
orphaning another. This made one get freed twice, and the other not at all.
Possible fix for bug 2963306 spotted by Doug Cuthbertson.
If you tried to build with automake-1.6 or earlier, we would
previously spit out pages and pages of garbage output. Now, automake
should just say "Hey, I'm not new enough for this."
AC_LIBOBJ is really only meant for defining missing library functions,
not conditional code compilation. Sticking our conditionally compiled
modules in SYS_SRC should make stuff easier to maintain.
Previously it would only accept 2 iovecs at most, because our
previous_to_last nonsense didn't let it take any more. This forced us
to do more reallocations in some cases when an extra small malloc
would have sufficed.
This actually makes some of the code a lot simpler. The only
ones that actually used previous_to_last for anything were reserving
and committing space.
This is the first patch in a series to replace previous_to_last with
last_with_data. Currently, we can only use two partially empty chains
at the end of an evbuffer, so if we have one with 511 bytes free, and
another with 512 bytes free, and we try to do a 1024 byte read, we
can't just stick another chain on the end: we need to reallocate the
last one. That's stupid and inefficient.
Instead, this patch adds a last_with_data pointer to eventually
replace previous_to_last. Instead of pointing to the penultimated
chain (if any) as previous_to_last does, last_with_data points to the
last chain that has any data in it, if any. If all chains are empty,
last_with_data points to the first chain. If there are no chains,
last_with_data is NULL.
The next step is to start using last_with_data everywhere that we
currently use previous_to_last. When that's done, we can remove
previous_to_last and the code that maintains it.
Once, for reasons that made sense at the time, we had evdns.c use its
own logging subsystem with two levels, "warn" and "debug". This leads
to problems, since setting a log handler for Libevent wouldn't actually
trap these messages, since they weren't on by default, and since some of
the warns should really be msgs.
This patch changes the default behavior of evdns.c to log to
event_(debugx,warnx,msgx) by default, and adds a new (internal-use-only)
log level of EVDNS_LOG_MSG. Programs that set a evdns logging
function will see no change. Programs that don't will now see evdns
warnings reported like other warnings.
Remeber, win32 has a socket type that's actually a handle, so if
there's a chance that code is run on win32, we can't use "int" as the
socket type.
This isn't a blind search-and-replace: sometimes an fd is really in
fact for a file, and not a socket at all.
This makes some cases of bench_http about 5% faster.
Our internal evbuffer_strpbrk() function was overly general (it tried
to handle all character sets when we only used it for "\r\n"), and
not very efficient (it called memchr once for each character in the
buffer until it found a \r or a \n). It actually showed up in some
profiles for HTTP testing, since evbuffer_readln() calls it when doing
loose CRLF detection. This patch replaces it with a faster
implementation.
These were introduced and deprecated in the same version (2.0.1-alpha),
presumably in two-stage process. Everybody sane should be using
evsignal_assign() and evsignal_new() instead.