Apparently some newer versions of mingw provide a fake pthreads api to
let applications work even if they don't know about windows threading.
That's nice, but we aren't one of those.
In many places throughout the code, we called _bufferevent_run_eventcb
without checking whether the eventcb was actually set. This would
work fine when the bufferevent's callbacks were deferred, but
otherwise the code would segfault. Strangely, we always remembered to
check before calling the _bufferevent_run_{read,write}cb functions.
To prevent similar errors in the future, all of
_buferevent_run_{read,write,event}cb now check to make sure the
callback is actually set before invoking or deferring the callback.
This patch also removes the now-redundant checks for {read,write}cb.
By default, the test.sh script still suppresses the output of all the
tests it invokes. Now, however, you can have that output written to
a file specified in the TEST_OUTPUT_FILE shell variable.
When we decide that a nameserver is down, we stop sending queries to
it, except to periodically probe it to see if it has come back up.
Our previous probe sechedule was an ad-hoc and hard-wired "10 seconds,
one minute, 5 minues, 15 minutes, 1 hour, 1 hour, 1 hour...". There
was nothing wrong with having it be ad-hoc, but making it hard-wired
served no good purpose.
Now the user can set the initial timeout via a new
"initial-probe-timeout:" option; future timeouts back off by a factor
of 3 on every failure to a maximum of 1 hour.
As a side-benefit, this lets us cut the runtime of the dns/retry test
from about 40 seconds to about 3 seconds. Faster unit tests are
always a good thing.
When I made the changes to release the base lock around the call to
port_getn(), I didn't add evthread-internal.h to the includes in
evport.c would build, and I didn't catch it since I haven't got a
Solaris host to build on. Tao Feng just reported this on
Libevent-users.
This is not part of the regression tests, since running it necessarily
takes a while. There is a new test-ratelim test; run it with '-h'
for an argument to see its options.
The fairness algorithms are not the best, not every bufferevent type
is supported, and some of the locking tricks here are simply absurd.
Still, this code should be a good first step.
Note that we've made two subtle mistakes: we are supposed to suffix
any non-released version with "-dev", and we're supposed to use the
last byte of the numeric version to indicate whether we have done this.
For example, when 2.0.4-alpha is released, its numeric versin will be
0x 02 00 04 00. As soon as we tag it, we will change the version in
the git repository to 2.0.4-alpha-dev, whose numeric version will be
0x 02 00 04 01 or something.
There are lots of things we do internally in bufferevents to indicate
"the user would like this operation to happen, but we aren't going to
try until some other condition goes away." Our logic here has gotten
entirely too complicated.
This patch tries to fix that by adding the idea of 'suspend flags' for
read and write. To say "don't bother reading or writing until
condition X no longer holds," bufferevent_suspend_read/write(bev,
BEV_SUSPEND_X). When X no longer holds, call
bufferevent_unsuspend_read/write(bev, BEV_SUSPEND_X).
Right now, only the read-watermark logic uses this.
William's original commit message:
Valgrind complains on startup because kq_init passes to kevent only
a partially initialized structure. The code doesn't expect kevent
to look at .fflags, .udata, or .data, I suppose, because it merely
tickles the kernel looking for an error response. But perhaps
that's unwarranted chuminess (notwithstanding that it's checking
for an OS X bug), and needless noise nonetheless.
There were a couple of places in the code where we manually kept lock
counts to make sure we never accessed resources without holding a
lock, and that we never released a lock we didn't have. The
lock-debugging code already puts counts on _every_ lock when lock
debugging is enabled, so there is no need to keep these counts around
otherwise. This patch rewrites the ASSERT_FOO_LOCKED macros to all
use a common EVLOCK_ASSERT_LOCKED().
We also teach the lock debugging code to keep track of who exactly
holds each lock, so that EVLOCK_ASSERT_LOCKED() means "locked by this
thread."
Original message:
evdns contains a bug related to thread lock.
enable thread lock by evthread_use_pthreads() will cause successive
evdns_base_resolve_ipv4() (and other resolve functions i think) to
hang on EVDNS_LOCK(base) after one or several successful call to
evdns_base_resolve_ipv4().