Browse files

Levent 2.0.10-stable

  • Loading branch information...
1 parent d34cc3b commit 0bf5b95fbe6a4becaddb2531733d30857afbd036 @jedisct1 committed Dec 16, 2010
Showing with 370 additions and 208 deletions.
  1. +19 −2 src/levent2/ChangeLog
  2. +4 −21 src/levent2/Makefile.am
  3. +7 −4 src/levent2/README
  4. +7 −1 src/levent2/buffer.c
  5. +1 −1 src/levent2/bufferevent-internal.h
  6. +1 −1 src/levent2/changelist-internal.h
  7. +2 −2 src/levent2/configure.in
  8. +10 −10 src/levent2/evdns.c
  9. +3 −0 src/levent2/event.c
  10. +7 −12 src/levent2/evmap.c
  11. +1 −1 src/levent2/evport.c
  12. +1 −1 src/levent2/evthread-internal.h
  13. +1 −1 src/levent2/evthread.c
  14. +1 −1 src/levent2/evthread_pthread.c
  15. +1 −1 src/levent2/evthread_win32.c
  16. +32 −17 src/levent2/evutil.c
  17. +23 −16 src/levent2/http.c
  18. +2 −2 src/levent2/include/event2/dns_compat.h
  19. +6 −4 src/levent2/include/event2/event.h
  20. +5 −4 src/levent2/include/event2/http.h
  21. +1 −1 src/levent2/ipv6-internal.h
  22. +5 −5 src/levent2/listener.c
  23. +1 −1 src/levent2/log-internal.h
  24. +1 −1 src/levent2/ratelim-internal.h
  25. +51 −1 src/levent2/sample/http-server.c
  26. +5 −5 src/levent2/test/bench_http.c
  27. +4 −4 src/levent2/test/bench_httpclient.c
  28. +1 −1 src/levent2/test/regress.c
  29. +7 −4 src/levent2/test/regress_dns.c
  30. +3 −3 src/levent2/test/regress_et.c
  31. +40 −1 src/levent2/test/regress_http.c
  32. +5 −5 src/levent2/test/regress_iocp.c
  33. +3 −3 src/levent2/test/regress_listener.c
  34. +6 −6 src/levent2/test/regress_main.c
  35. +1 −1 src/levent2/test/regress_minheap.c
  36. +8 −2 src/levent2/test/regress_rpc.c
  37. +5 −5 src/levent2/test/regress_ssl.c
  38. +5 −4 src/levent2/test/regress_testutils.c
  39. +1 −1 src/levent2/test/regress_testutils.h
  40. +2 −2 src/levent2/test/test-changelist.c
  41. +6 −6 src/levent2/test/test-ratelim.c
  42. +3 −3 src/levent2/test/test-time.c
  43. +4 −4 src/levent2/test/test-weof.c
  44. +1 −1 src/levent2/test/tinytest_local.h
  45. +5 −1 src/levent2/util-internal.h
  46. +62 −35 src/levent2/whatsnew-2.0.txt
View
21 src/levent2/ChangeLog
@@ -1,5 +1,22 @@
-Changes in version 2.0.10 (?? Dec 2010)
- [Not yet released; see Git log for more info]
+Changes in version 2.0.10-stable (16 Dec 2010)
+ [Autogenerated from the Git log, sorted and cleaned by hand.]
+BUGFIXES
+ o Minor fix for IOCP shutdown handling fix (2599b2d Kelly Brock)
+ o Correctly notify the main thread when activating an event from a subthread (5beeec9)
+ o Reject overlong http requests early when Expect:100-continue is set (d23839f Constantine Verutin)
+ o EVUTIL_ASSERT: Use sizeof() to avoid "unused variable" warnings with -DNDEBUG. (b63ab17 Evan Jones)
+
+CODE CLEANUPS
+ o bufferevent-internal.h: Use the new event2/util.h header, not evutil.h (ef5e65a Evan Jones)
+ o Use relative includes instead of system includes consistently. (fbe64f2 Evan Jones)
+ o Make whitespace more consistent
+
+TESTING
+ o tests: Use new event2 headers instead of old compatibility headers. (4f33209 Evan Jones)
+
+DOCUMENTATION
+ o Document that the cpu_hint is only used on Windows with IOCP for now (57689c4)
+ o Add stuff to "whats new in 2.0" based on reading include changes since August. (18adc3f)
Changes in 2.0.9-rc (30 Nov 2010):
View
25 src/levent2/Makefile.am
@@ -9,12 +9,10 @@ ACLOCAL_AMFLAGS = -I m4
# "Release" are never binary-compatible.
#
# This number incremented once for the 2.0 release candidate, and
-# shouldn't increment again until Libevent 3.0. Also, we shouldn't
-# increment to Libevent 3.0 unless we know in advance we're breaking
-# the ABI.
+# will increment for each series until we revise our interfaces enough
+# that we can seriously expect ABI compatibility between series.
#
-RELEASE = -release 2.0
-#RELEASE =
+RELEASE = -release 2.1
# This is the version info for the libevent binary API. It has three
# numbers:
@@ -34,24 +32,9 @@ RELEASE = -release 2.0
#
# Once an RC is out, DO NOT MAKE ANY ABI-BREAKING CHANGES IN THAT SERIES
# UNLESS YOU REALLY REALLY HAVE TO.
-VERSION_INFO = 5:0:0
+VERSION_INFO = 1:0:0
# History: RELEASE VERSION_INFO
-# 2.0.1-alpha -- 2.0 1:0:0
-# 2.0.2-alpha -- 2:0:0
-# 2.0.3-alpha -- 2:0:0 (should have incremented; didn't.)
-# 2.0.4-alpha -- 3:0:0
-# 2.0.5-beta -- 4:0:0
-# 2.0.6-rc -- 2.0 2:0:0
-# 2.0.7-rc -- 2.0 3:0:1
-# 2.0.8-rc -- 2.0 4:0:2
-# 2.0.9-rc -- 2.0 5:0:0 (ABI changed slightly)
-# Planned:
-# 2.0.10-stable-- 2.0 6:0:1 if the ABI changes compatibly,
-# or 5:1:0 if the ABI does not change,
-# or 6:0:0 if the ABI breaks
-#
-# For Libevent 2.1:
# 2.1.1-alpha -- 2.1 1:0:0
View
11 src/levent2/README
@@ -15,14 +15,14 @@ $ ./configure && make
first need to run the included "autogen.sh" script in order to
generate the configure script.)
-Install as root via
-
-# make install
-
You can run the regression tests by running
$ make verify
+Install as root via
+
+# make install
+
Before, reporting any problems, please run the regression tests.
To enable the low-level tracing build the library as:
@@ -82,6 +82,7 @@ fixing bugs:
Denis Bilenko
Julien Blache
Kevin Bowling
+ Kelly Brock
Ralph Castain
Shuo Chen
Ka-Hing Cheung
@@ -98,6 +99,7 @@ fixing bugs:
Aaron Hopkins
Tani Hosokawa
Claudio Jeker
+ Evan Jones
Valery Kyholodov
Marko Kreen
Scott Lamb
@@ -141,6 +143,7 @@ fixing bugs:
Brodie Thiesfield
Jason Toffaletti
Bas Verhoeven
+ Constantine Verutin
Zack Weinberg
Taral
propanbutan
View
8 src/levent2/buffer.c
@@ -246,6 +246,12 @@ evbuffer_chains_all_empty(struct evbuffer_chain *chain)
}
return 1;
}
+#else
+/* The definition is needed for EVUTIL_ASSERT, which uses sizeof to avoid
+"unused variable" warnings. */
+static inline int evbuffer_chains_all_empty(struct evbuffer_chain *chain) {
+ return 1;
+}
#endif
static void
@@ -2140,7 +2146,7 @@ evbuffer_readfile(struct evbuffer *buf, evutil_socket_t fd, ev_ssize_t howmuch)
/* XXX we _will_ waste some space here if there is any space left
* over on buf->last. */
nchains = evbuffer_reserve_space(buf, howmuch, v, 2);
- if (nchains < 1 || nchains > 2) {
+ if (nchains < 1 || nchains > 2) {
result = -1;
goto done;
}
View
2 src/levent2/bufferevent-internal.h
@@ -31,7 +31,7 @@ extern "C" {
#endif
#include "event2/event-config.h"
-#include "evutil.h"
+#include "event2/util.h"
#include "defer-internal.h"
#include "evthread-internal.h"
#include "event2/thread.h"
View
2 src/levent2/changelist-internal.h
@@ -47,7 +47,7 @@
reported spuriously.
*/
-#include <event2/util.h>
+#include "event2/util.h"
/** Represents a */
struct event_change {
View
4 src/levent2/configure.in
@@ -5,9 +5,9 @@ AC_INIT(event.c)
AC_CONFIG_MACRO_DIR([m4])
-AM_INIT_AUTOMAKE(libevent,2.0.9-rc-dev)
+AM_INIT_AUTOMAKE(libevent,2.1.0-alpha-dev)
AM_CONFIG_HEADER(config.h)
-AC_DEFINE(NUMERIC_VERSION, 0x02000901, [Numeric representation of the version])
+AC_DEFINE(NUMERIC_VERSION, 0x02010001, [Numeric representation of the version])
dnl Initialize prefix.
if test "$prefix" = "NONE"; then
View
20 src/levent2/evdns.c
@@ -68,16 +68,16 @@
#include <shlobj.h>
#endif
-#include <event2/dns.h>
-#include <event2/dns_struct.h>
-#include <event2/dns_compat.h>
-#include <event2/util.h>
-#include <event2/event.h>
-#include <event2/event_struct.h>
-#include <event2/thread.h>
-
-#include <event2/bufferevent.h>
-#include <event2/bufferevent_struct.h>
+#include "event2/dns.h"
+#include "event2/dns_struct.h"
+#include "event2/dns_compat.h"
+#include "event2/util.h"
+#include "event2/event.h"
+#include "event2/event_struct.h"
+#include "event2/thread.h"
+
+#include "event2/bufferevent.h"
+#include "event2/bufferevent_struct.h"
#include "bufferevent-internal.h"
#include "defer-internal.h"
View
3 src/levent2/event.c
@@ -2254,6 +2254,9 @@ event_active_nolock(struct event *ev, int res, short ncalls)
}
event_queue_insert(base, ev, EVLIST_ACTIVE);
+
+ if (EVBASE_NEED_NOTIFY(base))
+ evthread_notify_base(base);
}
void
View
19 src/levent2/evmap.c
@@ -685,14 +685,11 @@ event_changelist_del(struct event_base *base, evutil_socket_t fd, short old, sho
if (!change)
return -1;
- /* A delete removes any previous add, rather than replacing it:
- on those platforms where "add, delete, dispatch" is not the same
- as "no-op, dispatch", we want the no-op behavior.
-
- As well as checking the current operation we should also check
- the original set of events to make sure were not ignoring
- the case where the add operation is present on an event that
- was already set.
+ /* A delete on an event set that doesn't contain the event to be
+ deleted produces a no-op. This effectively emoves any previous
+ uncommitted add, rather than replacing it: on those platforms where
+ "add, delete, dispatch" is not the same as "no-op, dispatch", we
+ want the no-op behavior.
If we have a no-op item, we could remove it it from the list
entirely, but really there's not much point: skipping the no-op
@@ -704,15 +701,13 @@ event_changelist_del(struct event_base *base, evutil_socket_t fd, short old, sho
*/
if (events & (EV_READ|EV_SIGNAL)) {
- if (!(change->old_events & (EV_READ | EV_SIGNAL)) &&
- (change->read_change & EV_CHANGE_ADD))
+ if (!(change->old_events & (EV_READ | EV_SIGNAL)))
change->read_change = 0;
else
change->read_change = EV_CHANGE_DEL;
}
if (events & EV_WRITE) {
- if (!(change->old_events & EV_WRITE) &&
- (change->write_change & EV_CHANGE_ADD))
+ if (!(change->old_events & EV_WRITE))
change->write_change = 0;
else
change->write_change = EV_CHANGE_DEL;
View
2 src/levent2/evport.c
@@ -64,7 +64,7 @@
#include <time.h>
#include <unistd.h>
-#include <event2/thread.h>
+#include "event2/thread.h"
#include "evthread-internal.h"
#include "event-internal.h"
View
2 src/levent2/evthread-internal.h
@@ -30,7 +30,7 @@
extern "C" {
#endif
-#include <event2/thread.h>
+#include "event2/thread.h"
#include "event2/event-config.h"
#include "util-internal.h"
View
2 src/levent2/evthread.c
@@ -28,7 +28,7 @@
#ifndef _EVENT_DISABLE_THREAD_SUPPORT
-#include <event2/thread.h>
+#include "event2/thread.h"
#include <stdlib.h>
#include <string.h>
View
2 src/levent2/evthread_pthread.c
@@ -30,7 +30,7 @@
#include <pthread.h>
struct event_base;
-#include <event2/thread.h>
+#include "event2/thread.h"
#include <stdlib.h>
#include <string.h>
View
2 src/levent2/evthread_win32.c
@@ -34,7 +34,7 @@
#endif
struct event_base;
-#include <event2/thread.h>
+#include "event2/thread.h"
#include "mm-internal.h"
#include "evthread-internal.h"
View
49 src/levent2/evutil.c
@@ -364,26 +364,41 @@ evutil_strtoll(const char *s, char **endptr, int base)
}
#ifndef _EVENT_HAVE_GETTIMEOFDAY
-/* No gettimeofday; this muse be windows. */
+/* No gettimeofday; this must be windows. */
int
evutil_gettimeofday(struct timeval *tv, struct timezone *tz)
{
- struct _timeb tb;
+#ifdef _MSC_VER
+#define U64_LITERAL(n) n##ui64
+#else
+#define U64_LITERAL(n) n##llu
+#endif
+
+ /* Conversion logic taken from Tor, which in turn took it
+ * from Perl. GetSystemTimeAsFileTime returns its value as
+ * an unaligned (!) 64-bit value containing the number of
+ * 100-nanosecond intervals since 1 January 1601 UTC. */
+#define EPOCH_BIAS U64_LITERAL(116444736000000000)
+#define UNITS_PER_SEC U64_LITERAL(10000000)
+#define USEC_PER_SEC U64_LITERAL(1000000)
+#define UNITS_PER_USEC U64_LITERAL(10)
+ union {
+ FILETIME ft_ft;
+ ev_uint64_t ft_64;
+ } ft;
if (tv == NULL)
return -1;
- /* XXXX
- * _ftime is not the greatest interface here; GetSystemTimeAsFileTime
- * would give us better resolution, whereas something cobbled together
- * with GetTickCount could maybe give us monotonic behavior.
- *
- * Either way, I think this value might be skewed to ignore the
- * timezone, and just return local time. That's not so good.
- */
- _ftime(&tb);
- tv->tv_sec = (long) tb.time;
- tv->tv_usec = ((int) tb.millitm) * 1000;
+ GetSystemTimeAsFileTime(&ft.ft_ft);
+
+ if (EVUTIL_UNLIKELY(ft.ft_64 < EPOCH_BIAS)) {
+ /* Time before the unix epoch. */
+ return -1;
+ }
+ ft.ft_64 -= EPOCH_BIAS;
+ tv->tv_sec = (long) (ft.ft_64 / UNITS_PER_SEC);
+ tv->tv_usec = (long) ((ft.ft_64 / UNITS_PER_USEC) % USEC_PER_SEC);
return 0;
}
#endif
@@ -1485,11 +1500,11 @@ evutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap)
r = _vscprintf(format, ap);
#elif defined(sgi)
/* Make sure we always use the correct vsnprintf on IRIX */
- extern int _xpg5_vsnprintf(char * __restrict,
- __SGI_LIBC_NAMESPACE_QUALIFIER size_t,
+ extern int _xpg5_vsnprintf(char * __restrict,
+ __SGI_LIBC_NAMESPACE_QUALIFIER size_t,
const char * __restrict, /* va_list */ char *);
-
- r = _xpg5_vsnprintf(buf, buflen, format, ap);
+
+ r = _xpg5_vsnprintf(buf, buflen, format, ap);
#else
r = vsnprintf(buf, buflen, format, ap);
#endif
View
39 src/levent2/http.c
@@ -1484,7 +1484,7 @@ evhttp_parse_request_line(struct evhttp_request *req, char *line)
scheme = evhttp_uri_get_scheme(req->uri_elems);
hostname = evhttp_uri_get_host(req->uri_elems);
if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") ||
- !evutil_ascii_strcasecmp(scheme, "https")) &&
+ !evutil_ascii_strcasecmp(scheme, "https")) &&
hostname &&
!evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
req->flags |= EVHTTP_PROXY_REQUEST;
@@ -1836,7 +1836,7 @@ evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
}
/* Should we send a 100 Continue status line? */
- if (req->kind == EVHTTP_REQUEST && REQ_VERSION_ATLEAST(req, 1, 1)) {
+ if (req->kind == EVHTTP_REQUEST && REQ_VERSION_ATLEAST(req, 1, 1)) {
const char *expect;
expect = evhttp_find_header(req->input_headers, "Expect");
@@ -1848,6 +1848,12 @@ evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
no, we should respond with an error. For
now, just optimistically tell the client to
send their message body. */
+ if (req->ntoread > 0 &&
+ (size_t)req->ntoread > req->evcon->max_body_size) {
+ evhttp_send_error(req, HTTP_ENTITYTOOLARGE,
+ NULL);
+ return;
+ }
if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
evhttp_send_continue(evcon, req);
} else {
@@ -2746,7 +2752,7 @@ evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
size_t offset = 0;
char *translated;
const char *path;
-
+
/* Test for different URLs */
path = evhttp_uri_get_path(req->uri_elems);
offset = strlen(path);
@@ -3070,11 +3076,12 @@ evhttp_new_object(void)
http->timeout = -1;
evhttp_set_max_headers_size(http, EV_SIZE_MAX);
evhttp_set_max_body_size(http, EV_SIZE_MAX);
- evhttp_set_allowed_methods(http, EVHTTP_REQ_GET |
- EVHTTP_REQ_POST |
- EVHTTP_REQ_HEAD |
- EVHTTP_REQ_PUT |
- EVHTTP_REQ_DELETE);
+ evhttp_set_allowed_methods(http,
+ EVHTTP_REQ_GET |
+ EVHTTP_REQ_POST |
+ EVHTTP_REQ_HEAD |
+ EVHTTP_REQ_PUT |
+ EVHTTP_REQ_DELETE);
TAILQ_INIT(&http->sockets);
TAILQ_INIT(&http->callbacks);
@@ -3222,10 +3229,10 @@ evhttp_remove_server_alias(struct evhttp *http, const char *alias)
mm_free(evalias->alias);
mm_free(evalias);
return 0;
- }
+ }
}
- return -1;
+ return -1;
}
void
@@ -3382,7 +3389,7 @@ evhttp_request_free(struct evhttp_request *req)
mm_free(req->response_code_line);
if (req->host_cache != NULL)
mm_free(req->host_cache);
-
+
evhttp_clear_headers(req->input_headers);
mm_free(req->input_headers);
@@ -3461,10 +3468,10 @@ evhttp_request_get_host(struct evhttp_request *req)
if (!host && req->input_headers) {
const char *p;
size_t len;
-
+
host = evhttp_find_header(req->input_headers, "Host");
/* The Host: header may include a port. Remove it here
- to be consistent with uri_elems case above. */
+ to be consistent with uri_elems case above. */
if (host) {
p = host + strlen(host) - 1;
while (p > host && EVUTIL_ISDIGIT(*p))
@@ -3482,7 +3489,7 @@ evhttp_request_get_host(struct evhttp_request *req)
}
}
}
-
+
return host;
}
@@ -3585,7 +3592,7 @@ evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
req->flags |= EVHTTP_REQ_OWN_CONNECTION;
/* We did not present the request to the user user yet, so treat it as
- * if the user was done with the request. This allows us to free the
+ * if the user was done with the request. This allows us to free the
* request on a persistent connection if the client drops it without
* sending a request.
*/
@@ -4025,7 +4032,7 @@ evhttp_uri_parse(const char *source_uri)
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
- relative-ref = relative-part [ "?" query ] [ "#" fragment ]
+ relative-ref = relative-part [ "?" query ] [ "#" fragment ]
*/
View
4 src/levent2/include/event2/dns_compat.h
@@ -271,10 +271,10 @@ int evdns_set_option(const char *option, const char *val, int flags);
function is evdns_base_resolv_conf_parse().
@param flags any of DNS_OPTION_NAMESERVERS|DNS_OPTION_SEARCH|DNS_OPTION_MISC|
- DNS_OPTIONS_ALL
+ DNS_OPTIONS_ALL
@param filename the path to the resolv.conf file
@return 0 if successful, or various positive error codes if an error
- occurred (see above)
+ occurred (see above)
@see resolv.conf(3), evdns_config_windows_nameservers()
*/
int evdns_resolv_conf_parse(int flags, const char *const filename);
View
10 src/levent2/include/event2/event.h
@@ -244,7 +244,8 @@ int event_config_set_flag(struct event_config *cfg, int flag);
/**
* Records a hint for the number of CPUs in the system. This is used for
- * tuning thread pools, etc, for optimal performance.
+ * tuning thread pools, etc, for optimal performance. In Libevent 2.0,
+ * it is only on Windows, and only when IOCP is in use.
*
* @param cfg the event configuration object
* @param cpus the number of cpus
@@ -754,9 +755,10 @@ const struct timeval *event_base_init_common_timeout(struct event_base *base,
@param realloc_fn A replacement for realloc
@param free_fn A replacement for free.
**/
-void event_set_mem_functions(void *(*malloc_fn)(size_t sz),
- void *(*realloc_fn)(void *ptr, size_t sz),
- void (*free_fn)(void *ptr));
+void event_set_mem_functions(
+ void *(*malloc_fn)(size_t sz),
+ void *(*realloc_fn)(void *ptr, size_t sz),
+ void (*free_fn)(void *ptr));
#define EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED
#endif
View
9 src/levent2/include/event2/http.h
@@ -58,6 +58,7 @@ struct event_base;
#define HTTP_BADREQUEST 400 /**< invalid http request was made */
#define HTTP_NOTFOUND 404 /**< could not find content for uri */
#define HTTP_BADMETHOD 405 /**< method not allowed for this uri */
+#define HTTP_ENTITYTOOLARGE 413 /**< */
#define HTTP_EXPECTATIONFAILED 417 /**< we can't handle this expectation */
#define HTTP_INTERNAL 500 /**< internal error */
#define HTTP_NOTIMPLEMENTED 501 /**< not implemented */
@@ -266,20 +267,20 @@ int evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost);
/**
Add a server alias to an http object. The http object can be a virtual
- host or the main server.
+ host or the main server.
@param http the evhttp object
@param alias the alias to add
- @see evhttp_add_remove_alias()
+ @see evhttp_add_remove_alias()
*/
int evhttp_add_server_alias(struct evhttp *http, const char *alias);
/**
Remove a server alias from an http object.
-
+
@param http the evhttp object
@param alias the alias to remove
- @see evhttp_add_server_alias()
+ @see evhttp_add_server_alias()
*/
int evhttp_remove_server_alias(struct evhttp *http, const char *alias);
View
2 src/levent2/ipv6-internal.h
@@ -35,7 +35,7 @@
#include <sys/socket.h>
#endif
#include "event2/event-config.h"
-#include <event2/util.h>
+#include "event2/util.h"
#ifdef __cplusplus
extern "C" {
View
10 src/levent2/listener.c
@@ -44,10 +44,10 @@
#include <unistd.h>
#endif
-#include <event2/listener.h>
-#include <event2/util.h>
-#include <event2/event.h>
-#include <event2/event_struct.h>
+#include "event2/listener.h"
+#include "event2/util.h"
+#include "event2/event.h"
+#include "event2/event_struct.h"
#include "mm-internal.h"
#include "util-internal.h"
#include "log-internal.h"
@@ -615,7 +615,7 @@ accepted_socket_invoke_user_cb(struct deferred_cb *dcb, void *arg)
/* We need to call this so getsockname, getpeername, and
* shutdown work correctly on the accepted socket. */
/* XXXX handle error? */
- setsockopt(as->s, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
+ setsockopt(sock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
(char *)&as->lev->fd, sizeof(&as->lev->fd));
}
data = lev->user_data;
View
2 src/levent2/log-internal.h
@@ -27,7 +27,7 @@
#ifndef _LOG_H_
#define _LOG_H_
-#include <event2/util.h>
+#include "event2/util.h"
#ifdef __GNUC__
#define EV_CHECK_FMT(a,b) __attribute__((format(printf, a, b)))
View
2 src/levent2/ratelim-internal.h
@@ -30,7 +30,7 @@
extern "C" {
#endif
-#include <event2/util.h>
+#include "event2/util.h"
/** A token bucket is an internal structure that tracks how many bytes we are
* currently willing to read or write on a given bufferevent or group of
View
52 src/levent2/sample/http-server.c
@@ -11,10 +11,14 @@
#include <string.h>
#include <sys/types.h>
+#include <sys/stat.h>
#ifdef WIN32
#include <winsock2.h>
+#include <ws2tcpip.h>
#include <windows.h>
+#include <io.h>
+#include <fcntl.h>
#else
#include <sys/stat.h>
#include <sys/socket.h>
@@ -30,6 +34,18 @@
#include <event2/util.h>
#include <event2/keyvalq_struct.h>
+#ifdef _EVENT_HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef WIN32
+#define stat _stat
+#define fstat _fstat
+#define open _open
+#define close _close
+#define O_RDONLY _O_RDONLY
+#endif
+
char uri_root[512];
static const struct table_entry {
@@ -178,15 +194,35 @@ send_document_cb(struct evhttp_request *req, void *arg)
if (S_ISDIR(st.st_mode)) {
/* If it's a directory, read the comments and make a little
* index page */
+#ifdef WIN32
+ HANDLE d;
+ WIN32_FIND_DATAA ent;
+ char *pattern;
+ size_t dirlen;
+#else
DIR *d;
struct dirent *ent;
+#endif
const char *trailing_slash = "";
if (!strlen(path) || path[strlen(path)-1] != '/')
trailing_slash = "/";
+#ifdef WIN32
+ dirlen = strlen(whole_path);
+ pattern = malloc(dirlen+3);
+ memcpy(pattern, whole_path, dirlen);
+ pattern[dirlen] = '\\';
+ pattern[dirlen+1] = '*';
+ pattern[dirlen+2] = '\0';
+ d = FindFirstFileA(pattern, &ent);
+ free(pattern);
+ if (d == INVALID_HANDLE_VALUE)
+ goto err;
+#else
if (!(d = opendir(whole_path)))
goto err;
+#endif
close(fd);
evbuffer_add_printf(evb, "<html>\n <head>\n"
@@ -200,13 +236,27 @@ send_document_cb(struct evhttp_request *req, void *arg)
uri_root, path, /* XXX html-escape this? */
trailing_slash,
decoded_path /* XXX html-escape this */);
+#ifdef WIN32
+ do {
+ const char *name = ent.cFileName;
+#else
while ((ent = readdir(d))) {
+ const char *name = ent->d_name;
+#endif
evbuffer_add_printf(evb,
" <li><a href=\"%s\">%s</a>\n",
- ent->d_name, ent->d_name);/* XXX escape this */
+ name, name);/* XXX escape this */
+#ifdef WIN32
+ } while (FindNextFileA(d, &ent));
+#else
}
+#endif
evbuffer_add_printf(evb, "</ul></body></html>\n");
+#ifdef WIN32
+ CloseHandle(d);
+#else
closedir(d);
+#endif
evhttp_add_header(evhttp_request_get_output_headers(req),
"Content-Type", "text/html");
} else {
View
10 src/levent2/test/bench_http.c
@@ -42,11 +42,11 @@
#include <string.h>
#include <errno.h>
-#include <event2/event.h>
-#include <event2/buffer.h>
-#include <event2/util.h>
-#include <event2/http.h>
-#include <event2/thread.h>
+#include "event2/event.h"
+#include "event2/buffer.h"
+#include "event2/util.h"
+#include "event2/http.h"
+#include "event2/thread.h"
static void http_basic_cb(struct evhttp_request *req, void *arg);
View
8 src/levent2/test/bench_httpclient.c
@@ -35,10 +35,10 @@
#include <stdlib.h>
#include <errno.h>
-#include <event2/event.h>
-#include <event2/bufferevent.h>
-#include <event2/buffer.h>
-#include <event2/util.h>
+#include "event2/event.h"
+#include "event2/bufferevent.h"
+#include "event2/buffer.h"
+#include "event2/util.h"
/* for EVUTIL_ERR_CONNECT_RETRIABLE macro */
#include "util-internal.h"
View
2 src/levent2/test/regress.c
@@ -1422,7 +1422,7 @@ static void
test_nonpersist_readd(void)
{
struct event ev1, ev2;
-
+
setup_test("Re-add nonpersistent events: ");
event_set(&ev1, pair[0], EV_READ, re_add_read_cb, &ev2);
event_set(&ev2, pair[1], EV_READ, re_add_read_cb, &ev1);
View
11 src/levent2/test/regress_dns.c
@@ -58,12 +58,15 @@
#include <string.h>
#include <errno.h>
+#include "event2/dns.h"
+#include "event2/dns_compat.h"
+#include "event2/dns_struct.h"
#include "event2/event.h"
#include "event2/event_compat.h"
-#include <event2/util.h>
-#include <event2/listener.h>
-#include <event2/bufferevent.h>
-#include "evdns.h"
+#include "event2/event_struct.h"
+#include "event2/util.h"
+#include "event2/listener.h"
+#include "event2/bufferevent.h"
#include "log-internal.h"
#include "regress.h"
#include "regress_testutils.h"
View
6 src/levent2/test/regress_et.c
@@ -24,7 +24,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <event2/event-config.h>
+#include "event2/event-config.h"
#ifdef WIN32
#include <winsock2.h>
@@ -44,8 +44,8 @@
#endif
#include <errno.h>
-#include <event2/event.h>
-#include <event2/util.h>
+#include "event2/event.h"
+#include "event2/util.h"
#include "regress.h"
View
41 src/levent2/test/regress_http.c
@@ -1503,10 +1503,31 @@ http_post_test(void *arg)
event_base_dispatch(data->base);
+ tt_int_op(test_ok, ==, 1);
+
+ test_ok = 0;
+
+ req = evhttp_request_new(http_postrequest_done, data->base);
+ tt_assert(req);
+
+ /* Now try with 100-continue. */
+
+ /* Add the information that we care about */
+ evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost");
+ evhttp_add_header(evhttp_request_get_output_headers(req), "Expect", "100-continue");
+ evbuffer_add_printf(evhttp_request_get_output_buffer(req), POST_DATA);
+
+ if (evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/postit") == -1) {
+ tt_abort_msg("Couldn't make request");
+ }
+
+ event_base_dispatch(data->base);
+
+ tt_int_op(test_ok, ==, 1);
+
evhttp_connection_free(evcon);
evhttp_free(http);
- tt_int_op(test_ok, ==, 1);
end:
;
}
@@ -3253,6 +3274,15 @@ http_data_length_constraints_test_done(struct evhttp_request *req, void *arg)
}
static void
+http_large_entity_test_done(struct evhttp_request *req, void *arg)
+{
+ tt_assert(req);
+ tt_int_op(evhttp_request_get_response_code(req), ==, HTTP_ENTITYTOOLARGE);
+end:
+ event_base_loopexit(arg, NULL);
+}
+
+static void
http_data_length_constraints_test(void *arg)
{
struct basic_test_data *data = arg;
@@ -3310,6 +3340,15 @@ http_data_length_constraints_test(void *arg)
}
event_base_dispatch(data->base);
+ req = evhttp_request_new(http_large_entity_test_done, data->base);
+ evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost");
+ evhttp_add_header(evhttp_request_get_output_headers(req), "Expect", "100-continue");
+ evbuffer_add_printf(evhttp_request_get_output_buffer(req), "%s", long_str);
+ if (evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/") == -1) {
+ tt_abort_msg("Couldn't make request");
+ }
+ event_base_dispatch(data->base);
+
test_ok = 1;
end:
if (evcon)
View
10 src/levent2/test/regress_iocp.c
@@ -26,11 +26,11 @@
#include <stdlib.h>
#include <string.h>
-#include <event2/event.h>
-#include <event2/thread.h>
-#include <event2/buffer.h>
-#include <event2/buffer_compat.h>
-#include <event2/bufferevent.h>
+#include "event2/event.h"
+#include "event2/thread.h"
+#include "event2/buffer.h"
+#include "event2/buffer_compat.h"
+#include "event2/bufferevent.h"
#include <winsock2.h>
#include <ws2tcpip.h>
View
6 src/levent2/test/regress_listener.c
@@ -39,9 +39,9 @@
#include <string.h>
-#include <event2/listener.h>
-#include <event2/event.h>
-#include <event2/util.h>
+#include "event2/listener.h"
+#include "event2/event.h"
+#include "event2/util.h"
#include "regress.h"
#include "tinytest.h"
View
12 src/levent2/test/regress_main.c
@@ -64,12 +64,12 @@
#include <string.h>
#include <assert.h>
-#include <event2/util.h>
-#include <event2/event.h>
-#include <event2/event_compat.h>
-#include <event2/dns.h>
-#include <event2/dns_compat.h>
-#include <event2/thread.h>
+#include "event2/util.h"
+#include "event2/event.h"
+#include "event2/event_compat.h"
+#include "event2/dns.h"
+#include "event2/dns_compat.h"
+#include "event2/thread.h"
#include "event2/event-config.h"
#include "regress.h"
View
2 src/levent2/test/regress_minheap.c
@@ -25,7 +25,7 @@
*/
#include <stdlib.h>
-#include <event2/event_struct.h>
+#include "event2/event_struct.h"
#include "tinytest.h"
#include "tinytest_macros.h"
View
10 src/levent2/test/regress_rpc.c
@@ -54,11 +54,17 @@
#include <errno.h>
#include <assert.h>
+#include "event2/buffer.h"
#include "event2/event.h"
-#include "evhttp.h"
-#include "log-internal.h"
+#include "event2/event_compat.h"
+#include "event2/http.h"
+#include "event2/http_compat.h"
+#include "event2/http_struct.h"
+#include "event2/rpc.h"
#include "event2/rpc.h"
#include "event2/rpc_struct.h"
+#include "event2/tag.h"
+#include "log-internal.h"
#include "regress.gen.h"
View
10 src/levent2/test/regress_ssl.c
@@ -34,11 +34,11 @@
#include <netinet/in.h>
#endif
-#include <event2/util.h>
-#include <event2/event.h>
-#include <event2/bufferevent_ssl.h>
-#include <event2/buffer.h>
-#include <event2/listener.h>
+#include "event2/util.h"
+#include "event2/event.h"
+#include "event2/bufferevent_ssl.h"
+#include "event2/buffer.h"
+#include "event2/listener.h"
#include "regress.h"
#include "tinytest.h"
View
9 src/levent2/test/regress_testutils.c
@@ -57,12 +57,13 @@
#include <string.h>
#include <errno.h>
+#include "event2/dns.h"
+#include "event2/dns_struct.h"
#include "event2/event.h"
#include "event2/event_compat.h"
-#include <event2/util.h>
-#include <event2/listener.h>
-#include <event2/bufferevent.h>
-#include "evdns.h"
+#include "event2/util.h"
+#include "event2/listener.h"
+#include "event2/bufferevent.h"
#include "log-internal.h"
#include "regress.h"
#include "regress_testutils.h"
View
2 src/levent2/test/regress_testutils.h
@@ -27,7 +27,7 @@
#ifndef _TESTUTILS_H
#define _TESTUTILS_H
-#include <event2/dns.h>
+#include "event2/dns.h"
struct regress_dns_server_table {
const char *q;
View
4 src/levent2/test/test-changelist.c
@@ -25,8 +25,8 @@
#include <string.h>
#include <errno.h>
-#include <event2/event.h>
-#include <event2/util.h>
+#include "event2/event.h"
+#include "event2/util.h"
#include <time.h>
struct cpu_usage_timer {
View
12 src/levent2/test/test-ratelim.c
@@ -39,12 +39,12 @@
#endif
#include <signal.h>
-#include <event2/bufferevent.h>
-#include <event2/buffer.h>
-#include <event2/event.h>
-#include <event2/util.h>
-#include <event2/listener.h>
-#include <event2/thread.h>
+#include "event2/bufferevent.h"
+#include "event2/buffer.h"
+#include "event2/event.h"
+#include "event2/util.h"
+#include "event2/listener.h"
+#include "event2/thread.h"
static int cfg_verbose = 0;
static int cfg_help = 0;
View
6 src/levent2/test/test-time.c
@@ -16,9 +16,9 @@
#endif
#include <errno.h>
-#include <event2/event.h>
-#include <event2/event_compat.h>
-#include <event2/event_struct.h>
+#include "event2/event.h"
+#include "event2/event_compat.h"
+#include "event2/event_struct.h"
int called = 0;
View
8 src/levent2/test/test-weof.c
@@ -24,10 +24,10 @@
#include <signal.h>
#include <errno.h>
-#include <event2/event.h>
-#include <event2/event_struct.h>
-#include <event2/event_compat.h>
-#include <event2/util.h>
+#include "event2/event.h"
+#include "event2/event_struct.h"
+#include "event2/event_compat.h"
+#include "event2/util.h"
#ifdef _EVENT___func__
#define __func__ _EVENT___func__
View
2 src/levent2/test/tinytest_local.h
@@ -3,7 +3,7 @@
#include <winsock2.h>
#endif
-#include <event2/util.h>
+#include "event2/util.h"
#include "util-internal.h"
#define snprintf evutil_snprintf
View
6 src/levent2/util-internal.h
@@ -52,6 +52,10 @@ extern "C" {
/* A good no-op to use in macro definitions. */
#define _EVUTIL_NIL_STMT ((void)0)
+/* Suppresses the compiler's "unused variable" warnings for unused assert. */
+#define _EVUTIL_NIL_CONDITION(condition) do { \
+ (void)sizeof(condition); \
+} while(0)
/* Internal use only: macros to match patterns of error codes in a
cross-platform way. We need these macros because of two historical
@@ -177,7 +181,7 @@ long _evutil_weakrand(void);
/* Replacement for assert() that calls event_errx on failure. */
#ifdef NDEBUG
-#define EVUTIL_ASSERT(cond) _EVUTIL_NIL_STMT
+#define EVUTIL_ASSERT(cond) _EVUTIL_NIL_CONDITION(cond)
#define EVUTIL_FAILURE_CHECK(cond) 0
#else
#define EVUTIL_ASSERT(cond) \
View
97 src/levent2/whatsnew-2.0.txt
@@ -8,11 +8,7 @@ What's New In Libevent 2.0 so far:
Libevent 2.0, from a user's point of view. It was most recently
updated based on features in git master as of August 2010.
- NOTE 1: If any features or fixes get backported from trunk to 1.4,
- they should get moved from here into whatsnew-14.txt, since they
- will no longer be differences between 1.4 and this version.
-
- NOTE 2: I am very sure that I missed some thing on this list. Caveat
+ NOTE: I am very sure that I missed some thing on this list. Caveat
haxxor.
1.2. Better documentation
@@ -56,15 +52,16 @@ What's New In Libevent 2.0 so far:
Finally, there are *structure headers*, like event2/event_struct.h.
These headers contain definitions of some structures that Libevent has
- historically exposed. Exposing them caused problems in the past, since
- programs that were compiled to work with one version of Libevent would
- often stop working with another version that changed the size or layout
- of some object. We've moving them into separate headers so that
- programmers can know that their code is not depending on any unstable
- aspect of the Libvent ABI. New programs should generally not include
- these headers unless they really know what they are doing, and are
- willing to rebuild their software whenever they want to link it against a
- new version of libevent.
+ historically exposed. Exposing them caused problems in the past,
+ since programs that were compiled to work with one version of Libevent
+ would often stop working with another version that changed the size or
+ layout of some object. We've moving them into separate headers so
+ that programmers can know that their code is not depending on any
+ unstable aspect of the Libvent ABI. New programs should generally not
+ include these headers unless they really know what they are doing, are
+ willing to rebuild their software whenever they want to link it
+ against a new version of Libevent, and are willing to risk their code
+ breaking if and when data structures change.
Functionality that once was located in event.h is now more subdivided.
The core event logic is now in event2/event.h. The "evbuffer" functions
@@ -116,8 +113,8 @@ What's New In Libevent 2.0 so far:
#include <event.h>
...
struct event *ev = malloc(sizeof(struct event));
- /* This call will cause a stack overrun if you compile with one version
- of libevent and link dynamically against another. */
+ /* This call will cause a buffer overrun if you compile with one version
+ of Libevent and link dynamically against another. */
event_set(ev, fd, EV_READ, cb, NULL);
/* If you forget this call, your code will break in hard-to-diagnose
ways in the presence of multiple event bases. */
@@ -214,9 +211,7 @@ What's New In Libevent 2.0 so far:
2.8. evthread_* functions for thread-safe structures.
- Libevent structures can now be built with locking support. You can enable
- this on a per-event-base level by writing functions to implement mutexes
- and thread IDs, and passing them to evthread_set_lock_callbacks. This
+ Libevent structures can now be built with locking support. This code
makes it safe to add, remove, and activate events on an event base from a
different thread. (Previously, if you wanted to write multithreaded code
with Libevent, you could only an event_base or its events in one thread at
@@ -230,6 +225,11 @@ What's New In Libevent 2.0 so far:
If you want threading support and you're using Windows, you can just
call evthread_use_windows_threads().
+ If you are using some locking system besides Windows and pthreads, You
+ can enable this on a per-event-base level by writing functions to
+ implement mutexes, conditions, and thread IDs, and passing them to
+ evthread_set_lock_callbacks and related functions in event2/thread.h.
+
Once locking functions are enabled, every new event_base is created with a
lock. You can prevent a single event_base from being built with a lock
disabled by using the EVENT_BASE_FLAG_NOLOCK flag in its
@@ -239,7 +239,7 @@ What's New In Libevent 2.0 so far:
the event loop.
To make an evbuffer or a bufferevent object threadsafe, call its
- _enable_locking() function.
+ *_enable_locking() function.
The HTTP api is not currently threadsafe.
@@ -290,6 +290,13 @@ What's New In Libevent 2.0 so far:
redundant adds and deletes, and performs no more operations than necessary
at the kernel level.
+ This logic is on for the kqueue backend, and available (but off by
+ default) for the epoll backend. To turn it on for the epoll backend,
+ set the EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST flag in the
+ event_base_cofig, or set the EVENT_EPOLL_USE_CHANGELIST environment
+ variable. Doing this with epoll may result in weird bugs if you give
+ any fds closed by dup() or its variants.
+
3.2. Improved notification on Linux
When we need to wake the event loop up from another thread, we use
@@ -298,8 +305,8 @@ What's New In Libevent 2.0 so far:
3.3. Windows: better support for everything
- Bufferevents on windows can use a new mechanism (off-by-default; see below)
- to send their data via windows overlapped IO and get their notifications
+ Bufferevents on Windows can use a new mechanism (off-by-default; see below)
+ to send their data via Windows overlapped IO and get their notifications
via the IOCP API. This should be much faster than using event-based
notification.
@@ -312,10 +319,10 @@ What's New In Libevent 2.0 so far:
event are now done with O(1) hash tables rather than O(lg n) red-black
trees.
- Unfortunately, the main windows backend is still select()-based: from
+ Unfortunately, the main Windows backend is still select()-based: from
testing the IOCP backends on the mailing list, it seems that there isn't
- actually a way to tell for certain whether a socket is writable with IOCP
- without . Libevent 2.1 may add a multithreaded WaitForMultipleEvents-based
+ actually a way to tell for certain whether a socket is writable with IOCP.
+ Libevent 2.1 may add a multithreaded WaitForMultipleEvents-based
backend for better performance with many inactive sockets and better
integration with Windows events.
@@ -336,11 +343,12 @@ What's New In Libevent 2.0 so far:
Needless to say, this is a terrible interface for networked IO.
Now, evbuffers are implemented as a linked list of memory chunks, like
- most Unix kernels use for network IO. Data is added at the end of the
- linked list and removed from the front, so that we don't ever need
- realloc huge chunks or memmove the whole buffer contents.
+ most Unix kernels use for network IO. (See Linux's skbuf interfaces,
+ or *BSD's mbufs). Data is added at the end of the linked list and
+ removed from the front, so that we don't ever need realloc huge chunks
+ or memmove the whole buffer contents.
- To avoid multiple calls to read and write, we use the readv/writev
+ To avoid excessive calls to read and write, we use the readv/writev
interfaces (or WSASend/WSARecv on Windows) to do IO on multiple chunks at
once with a single system call.
@@ -508,13 +516,13 @@ What's New In Libevent 2.0 so far:
6. Other improvements
-6.1. DNS
+6.1. DNS improvements
-6.1.1. IPv6 nameservers
+6.1.1. DNS: IPv6 nameservers
The evdns code now lets you have nameservers whose addresses are IPv6.
-6.1.2: Better security.
+6.1.2. DNS: Better security
Libevent 2.0 tries harder to resist DNS answer-sniping attacks than
earlier versions of evdns. See comments in the code for full details.
@@ -524,7 +532,7 @@ What's New In Libevent 2.0 so far:
internal RNG to generate DNS transaction IDs, so you don't need to supply
your own.
-6.1.3. Getaddrinfo support
+6.1.3. DNS: Getaddrinfo support
There's now an asynchronous getaddrinfo clone, evdns_getaddrinfo(),
to make the results of the evdns functions more usable. It doesn't
@@ -539,7 +547,7 @@ What's New In Libevent 2.0 so far:
Bufferevents provide bufferevent_connect_hostname(), which combines
the name lookup and connect operations.
-6.1.4. No more evdns globals
+6.1.4. DNS: No more evdns globals
Like an event base, evdns operations are now supposed to use an evdns_base
argument. This makes them easier to wrap for other (more OO) languages,
@@ -552,7 +560,7 @@ What's New In Libevent 2.0 so far:
TCP connections. Just use the evconnlistener_*() functions in the
event2/listener.h header.
- The listener code supports IOCP on windows if available.
+ The listener code supports IOCP on Windows if available.
6.3. Secure RNG support
@@ -563,6 +571,25 @@ What's New In Libevent 2.0 so far:
can use the evutil_secure_rng_*() functions to access a fairly secure
random stream of bytes.
+6.4. HTTP
+
+ The evhttp uriencoding and uridecoding APIs have updated versions
+ that behave more correctly, and can handle strings with internal NULs.
+
+ The evhttp query parsing and URI parsing logic can now detect errors
+ more usefully. Moreover, we include an actual URI parsing function
+ (evhttp_uri_parse()) to correctly parse URIs, so as to discourage
+ people from rolling their own ad-hoc parsing functions.
+
+ There are now accessor functions for the useful fields of struct http
+ and friends; it shouldn't be necessary to access them directly any
+ more.
+
+ Libevent now lets you declare support for all specified HTTP methods,
+ including OPTIONS, PATCH, and so on. The default list is unchanged.
+
+ Numerous evhttp bugs also got fixed.
+
7. Infrastructure improvements
7.1. Better unit test framework

0 comments on commit 0bf5b95

Please sign in to comment.