The sendfile() implementation for evbuffer_add_file is potentially more
efficient, but it has a problem: you can only use it to send bytes over
a socket using sendfile(). If you are writing bytes via SSL_send() or
via a filter, or if you need to be able to inspect your buffer, it
doesn't work.
As an easy fix, this patch disables the sendfile-based implementation of
evbuffer_add_file on an evbuffer unless the user sets a new
EVBUFFER_FLAG_DRAINS_TO_FD flag on that evbuffer, indicating that the
evbuffer will not be inspected, but only written out via
evbuffer_write(), evbuffer_write_atmost(), or drained with stuff like
evbuffer_drain() or evbuffer_add_buffer(). This flag is off by
default, except for evbuffers used for output on bufferevent_socket.
In the future, it could be interesting to make a best-effort file
segment implementation that tries to send via sendfile, but mmaps on
demand. That's too much complexity for a stable release series, though.
The EVUTIL_CLOSESOCKET() macro required you to include unistd.h in your
source for POSIX. We might as well turn it into a function: an extra
function call is going to be cheap in comparison with the system call.
We retain the EVUTIL_CLOSESOCKET() macro as an alias for the new
evutil_closesocket() function.
(commit message from email by Nick and Sebastian)
There should be no need to call be_socket_enable: that does an
event_add(). What we really want to do is event_active(), to make
sure that the writecb is executed.
Also, there was one "} if () {" that was missing an else.
I've noted that the return value for evutil_socket_connect() is
getting screwy, but since that isn't an exported function, we can fix
it whenever.
The different bufferevent implementations had different behavior for
their timeouts. Some of them kept re-triggering the timeouts
indefinitely; some disabled the event immediately the first time a
timeout triggered. Some of them made the timeouts only count when
the bufferevent was actively trying to read or write; some did not.
The new behavior is modeled after old socket bufferevents, since
they were here first and their behavior is relatively sane.
Basically, each timeout disables the bufferevent's corresponding
read or write operation when it fires. Timeouts are stopped
whenever we suspend writing or reading, and reset whenever we
unsuspend writing or reading. Calling bufferevent_enable resets a
timeout, as does changing the timeout value.
When we're doing a lookup in preparation for doing a connect, we
might have an unconnected socket on hand, and mustn't actually do
any reading or writing with it.
Most of these should be unable to fail, since adding a timeout
generally always works. Still, it's better not to try to be "too
smart for our own good here."
There are some remaining event_add() calls that I didn't add checks
for; I've marked those with "XXXX" comments.
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.
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.
Basically, we only want to report the 'connected' event because of
the socket connect() finishing when we have an actual socket
bufferevent; on an SSL bufferevent, 'connected' means 'SSL
connection finished.'
This isn't FreeBSD's fault: it just has a connect() that tends to
succeed pretty early.
svn:r1548
This patch from Chris Davis saves some callback depth, and adds proper
ref-counting to bufferevents when there's a deferred evbuffer callback
inflight. It could use a couple more comments to really nail down what
its invariants are.
svn:r1543
The entry points are evutil_getaddrinfo and evdns_getaddrinfo respectively.
There are fairly extensive unit tests.
I believe this code conforms to RFC3493 pretty closely, but there are
probably more issues. It should get tested on more platforms.
This code means we can dump the well-intentioned but weirdly-implemented
bufferevent_evdns and evutil_resolve code.
svn:r1537
This is code by Chris Davis, with changes to get the unit tests failing less aggressively.
The unit tests for this code do not completely pass yet; Chris is looking into that. If they aren't passing by the next release, I'll turn off this code.
svn:r1499
This function, bufferevent_socket_connect_hostname() can either use
evdns to do the resolve, or use a new function (evutil_resolve) that
uses getaddrinfo or gethostbyname, like http.c does now.
This function is meant to eventually replace the hostname resolution mess in
http.c.
svn:r1496
This makes our interfaces usable from C++, which doesn't believe
you can say "bufferevent_socket_nase(base, -1,
BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS)" but which instead
would demand "static_cast<bufferevent_options>(BEV_OPT_CLOSE_ON_FREE|
BEV_OPT_DEFER_CALLBACKS))" for the last argument.
Diagnosis and patch from Chris Davis.
svn:r1456
Previously, if we had a socket bufferevent in connect state, we'd send
both of these to indicate that the connection was done. That was broken
since the point of adding BEV_EVENT_CONNECTED was so that we could
distinguish "we're connected" and "we wrote something".
Now, writecb is called only when
A) the connection finished but the user never put the socket into a
"connecting" state, or
B) data was actually written.
svn:r1425