Raise libevent dependency to 2.0.10-stable or newer

Only some very ancient distributions don't ship with Libevent 2 anymore,
even the oldest supported Ubuntu LTS version has it. This allows us to
get rid of a lot of compat code.
This commit is contained in:
Sebastian Hahn
2016-07-03 19:42:36 +02:00
parent ec6ea66240
commit 265e40b481
26 changed files with 31 additions and 4383 deletions
+3 -209
View File
@@ -19,15 +19,11 @@
#include "util.h"
#include "torlog.h"
#ifdef HAVE_EVENT2_EVENT_H
#include <event2/event.h>
#include <event2/thread.h>
#ifdef USE_BUFFEREVENTS
#include <event2/bufferevent.h>
#endif
#else
#include <event.h>
#endif
/** A string which, if it appears in a libevent log, should be ignored. */
static const char *suppress_msg = NULL;
@@ -69,6 +65,7 @@ configure_libevent_logging(void)
{
event_set_log_callback(libevent_logging_callback);
}
/** Ignore any libevent log message that contains <b>msg</b>. */
void
suppress_libevent_log_msg(const char *msg)
@@ -76,44 +73,6 @@ suppress_libevent_log_msg(const char *msg)
suppress_msg = msg;
}
#ifndef HAVE_EVENT2_EVENT_H
/** Work-alike replacement for event_new() on pre-Libevent-2.0 systems. */
struct event *
tor_event_new(struct event_base *base, int sock, short what,
void (*cb)(int, short, void *), void *arg)
{
struct event *e = tor_malloc_zero(sizeof(struct event));
event_set(e, sock, what, cb, arg);
if (! base)
base = tor_libevent_get_base();
event_base_set(base, e);
return e;
}
/** Work-alike replacement for evtimer_new() on pre-Libevent-2.0 systems. */
struct event *
tor_evtimer_new(struct event_base *base,
void (*cb)(int, short, void *), void *arg)
{
return tor_event_new(base, -1, 0, cb, arg);
}
/** Work-alike replacement for evsignal_new() on pre-Libevent-2.0 systems. */
struct event *
tor_evsignal_new(struct event_base * base, int sig,
void (*cb)(int, short, void *), void *arg)
{
return tor_event_new(base, sig, EV_SIGNAL|EV_PERSIST, cb, arg);
}
/** Work-alike replacement for event_free() on pre-Libevent-2.0 systems,
* except tolerate tor_event_free(NULL). */
void
tor_event_free(struct event *ev)
{
if (ev == NULL)
return;
event_del(ev);
tor_free(ev);
}
#else
/* Wrapper for event_free() that tolerates tor_event_free(NULL) */
void
tor_event_free(struct event *ev)
@@ -122,7 +81,6 @@ tor_event_free(struct event *ev)
return;
event_free(ev);
}
#endif
/** Global event base for use by the main thread. */
static struct event_base *the_event_base = NULL;
@@ -158,7 +116,6 @@ tor_libevent_initialize(tor_libevent_cfg *torcfg)
/* some paths below don't use torcfg, so avoid unused variable warnings */
(void)torcfg;
#ifdef HAVE_EVENT2_EVENT_H
{
int attempts = 0;
int using_threads;
@@ -190,16 +147,12 @@ tor_libevent_initialize(tor_libevent_cfg *torcfg)
event_config_set_flag(cfg, EVENT_BASE_FLAG_NOLOCK);
}
#if defined(LIBEVENT_VERSION_NUMBER) && LIBEVENT_VERSION_NUMBER >= V(2,0,7)
if (torcfg->num_cpus > 0)
event_config_set_num_cpus_hint(cfg, torcfg->num_cpus);
#endif
#if LIBEVENT_VERSION_NUMBER >= V(2,0,9)
/* We can enable changelist support with epoll, since we don't give
* Libevent any dup'd fds. This lets us avoid some syscalls. */
event_config_set_flag(cfg, EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST);
#endif
the_event_base = event_base_new_with_config(cfg);
@@ -223,9 +176,6 @@ tor_libevent_initialize(tor_libevent_cfg *torcfg)
goto retry;
}
}
#else
the_event_base = event_init();
#endif
if (!the_event_base) {
/* LCOV_EXCL_START */
@@ -255,62 +205,7 @@ tor_libevent_get_base, (void))
const char *
tor_libevent_get_method(void)
{
#ifdef HAVE_EVENT2_EVENT_H
return event_base_get_method(the_event_base);
#else
return event_get_method();
#endif
}
/** Return the le_version_t for the version of libevent specified in the
* string <b>v</b>. If the version is very new or uses an unrecognized
* version, format, return LE_OTHER. */
STATIC le_version_t
tor_decode_libevent_version(const char *v)
{
unsigned major, minor, patchlevel;
char c, e, extra;
int fields;
/* Try the new preferred "1.4.11-stable" format.
* Also accept "1.4.14b-stable". */
fields = tor_sscanf(v, "%u.%u.%u%c%c", &major, &minor, &patchlevel, &c, &e);
if (fields == 3 ||
((fields == 4 || fields == 5 ) && (c == '-' || c == '_')) ||
(fields == 5 && TOR_ISALPHA(c) && (e == '-' || e == '_'))) {
return V(major,minor,patchlevel);
}
/* Try the old "1.3e" format. */
fields = tor_sscanf(v, "%u.%u%c%c", &major, &minor, &c, &extra);
if (fields == 3 && TOR_ISALPHA(c)) {
return V_OLD(major, minor, c);
} else if (fields == 2) {
return V(major, minor, 0);
}
return LE_OTHER;
}
/** Return an integer representing the binary interface of a Libevent library.
* Two different versions with different numbers are sure not to be binary
* compatible. Two different versions with the same numbers have a decent
* chance of binary compatibility.*/
STATIC int
le_versions_compatibility(le_version_t v)
{
if (v == LE_OTHER)
return 0;
if (v < V_OLD(1,0,'c'))
return 1;
else if (v < V(1,4,0))
return 2;
else if (v < V(1,4,99))
return 3;
else if (v < V(2,0,1))
return 4;
else /* Everything 2.0 and later should be compatible. */
return 5;
}
/** Return a string representation of the version of the currently running
@@ -321,101 +216,14 @@ tor_libevent_get_version_str(void)
return event_get_version();
}
#if defined(LIBEVENT_VERSION)
#define HEADER_VERSION LIBEVENT_VERSION
#elif defined(_EVENT_VERSION)
#define HEADER_VERSION _EVENT_VERSION
#endif
/** Return a string representation of the version of Libevent that was used
* at compilation time. */
const char *
tor_libevent_get_header_version_str(void)
{
return HEADER_VERSION;
return LIBEVENT_VERSION;
}
/** See whether the headers we were built against differ from the library we
* linked against so much that we're likely to crash. If so, warn the
* user. */
void
tor_check_libevent_header_compatibility(void)
{
(void) le_versions_compatibility;
(void) tor_decode_libevent_version;
/* In libevent versions before 2.0, it's hard to keep binary compatibility
* between upgrades, and unpleasant to detect when the version we compiled
* against is unlike the version we have linked against. Here's how. */
#if defined(HEADER_VERSION)
/* We have a header-file version and a function-call version. Easy. */
if (strcmp(HEADER_VERSION, event_get_version())) {
le_version_t v1, v2;
int compat1 = -1, compat2 = -1;
int verybad;
v1 = tor_decode_libevent_version(HEADER_VERSION);
v2 = tor_decode_libevent_version(event_get_version());
compat1 = le_versions_compatibility(v1);
compat2 = le_versions_compatibility(v2);
verybad = compat1 != compat2;
tor_log(verybad ? LOG_WARN : LOG_NOTICE,
LD_GENERAL, "We were compiled with headers from version %s "
"of Libevent, but we're using a Libevent library that says it's "
"version %s.", HEADER_VERSION, event_get_version());
if (verybad)
log_warn(LD_GENERAL, "This will almost certainly make Tor crash.");
else
log_info(LD_GENERAL, "I think these versions are binary-compatible.");
}
#else
/* event_get_version but no _EVENT_VERSION. We might be in 1.4.0-beta or
earlier, where that's normal. To see whether we were compiled with an
earlier version, let's see whether the struct event defines MIN_HEAP_IDX.
*/
#ifdef HAVE_STRUCT_EVENT_MIN_HEAP_IDX
/* The header files are 1.4.0-beta or later. If the version is not
* 1.4.0-beta, we are incompatible. */
{
if (strcmp(event_get_version(), "1.4.0-beta")) {
log_warn(LD_GENERAL, "It's a little hard to tell, but you seem to have "
"Libevent 1.4.0-beta header files, whereas you have linked "
"against Libevent %s. This will probably make Tor crash.",
event_get_version());
}
}
#else
/* Our headers are 1.3e or earlier. If the library version is not 1.4.x or
later, we're probably fine. */
{
const char *v = event_get_version();
if ((v[0] == '1' && v[2] == '.' && v[3] > '3') || v[0] > '1') {
log_warn(LD_GENERAL, "It's a little hard to tell, but you seem to have "
"Libevent header file from 1.3e or earlier, whereas you have "
"linked against Libevent %s. This will probably make Tor "
"crash.", event_get_version());
}
}
#endif
/* Your libevent is ancient. */
#endif
}
/*
If possible, we're going to try to use Libevent's periodic timer support,
since it does a pretty good job of making sure that periodic events get
called exactly M seconds apart, rather than starting each one exactly M
seconds after the time that the last one was run.
*/
#ifdef HAVE_EVENT2_EVENT_H
#define HAVE_PERIODIC
#define PERIODIC_FLAGS EV_PERSIST
#else
#define PERIODIC_FLAGS 0
#endif
/** Represents a timer that's run every N microseconds by Libevent. */
struct periodic_timer_t {
/** Underlying event used to implement this periodic event. */
@@ -424,11 +232,6 @@ struct periodic_timer_t {
void (*cb)(struct periodic_timer_t *, void *);
/** User-supplied data for the callback */
void *data;
#ifndef HAVE_PERIODIC
/** If Libevent doesn't know how to invoke events every N microseconds,
* we'll need to remember the timeout interval here. */
struct timeval tv;
#endif
};
/** Libevent callback to implement a periodic event. */
@@ -438,10 +241,6 @@ periodic_timer_cb(evutil_socket_t fd, short what, void *arg)
periodic_timer_t *timer = arg;
(void) what;
(void) fd;
#ifndef HAVE_PERIODIC
/** reschedule the event as needed. */
event_add(timer->ev, &timer->tv);
#endif
timer->cb(timer, timer->data);
}
@@ -459,16 +258,13 @@ periodic_timer_new(struct event_base *base,
tor_assert(tv);
tor_assert(cb);
timer = tor_malloc_zero(sizeof(periodic_timer_t));
if (!(timer->ev = tor_event_new(base, -1, PERIODIC_FLAGS,
if (!(timer->ev = tor_event_new(base, -1, EV_PERSIST,
periodic_timer_cb, timer))) {
tor_free(timer);
return NULL;
}
timer->cb = cb;
timer->data = data;
#ifndef HAVE_PERIODIC
memcpy(&timer->tv, tv, sizeof(struct timeval));
#endif
event_add(timer->ev, (struct timeval *)tv); /*drop const for old libevent*/
return timer;
}
@@ -539,7 +335,6 @@ int
tor_init_libevent_rng(void)
{
int rv = 0;
#ifdef HAVE_EVUTIL_SECURE_RNG_INIT
char buf[256];
if (evutil_secure_rng_init() < 0) {
rv = -1;
@@ -547,7 +342,6 @@ tor_init_libevent_rng(void)
crypto_rand(buf, 32);
evutil_secure_rng_add_bytes(buf, 32);
evutil_secure_rng_get_bytes(buf, sizeof(buf));
#endif
return rv;
}
+1 -31
View File
@@ -15,32 +15,17 @@ struct ev_token_bucket_cfg;
struct bufferevent_rate_limit_group;
#endif
#ifdef HAVE_EVENT2_EVENT_H
#include <event2/util.h>
#elif !defined(EVUTIL_SOCKET_DEFINED)
#define EVUTIL_SOCKET_DEFINED
#define evutil_socket_t int
#endif
void configure_libevent_logging(void);
void suppress_libevent_log_msg(const char *msg);
#ifdef HAVE_EVENT2_EVENT_H
#define tor_event_new event_new
#define tor_evtimer_new evtimer_new
#define tor_evsignal_new evsignal_new
#define tor_evdns_add_server_port(sock, tcp, cb, data) \
evdns_add_server_port_with_base(tor_libevent_get_base(), \
(sock),(tcp),(cb),(data));
#else
struct event *tor_event_new(struct event_base * base, evutil_socket_t sock,
short what, void (*cb)(evutil_socket_t, short, void *), void *arg);
struct event *tor_evtimer_new(struct event_base * base,
void (*cb)(evutil_socket_t, short, void *), void *arg);
struct event *tor_evsignal_new(struct event_base * base, int sig,
void (*cb)(evutil_socket_t, short, void *), void *arg);
#define tor_evdns_add_server_port evdns_add_server_port
#endif
void tor_event_free(struct event *ev);
@@ -99,9 +84,7 @@ void tor_gettimeofday_cached_monotonic(struct timeval *tv);
byte is unused.
This is equivalent to the format of LIBEVENT_VERSION_NUMBER on Libevent
2.0.1 or later. For versions of Libevent before 1.4.0, which followed the
format of "1.0, 1.0a, 1.0b", we define 1.0 to be equivalent to 1.0.0, 1.0a
to be equivalent to 1.0.1, and so on.
2.0.1 or later.
*/
typedef uint32_t le_version_t;
@@ -109,23 +92,10 @@ typedef uint32_t le_version_t;
/** Macros: returns the number of a libevent version as a le_version_t */
#define V(major, minor, patch) \
(((major) << 24) | ((minor) << 16) | ((patch) << 8))
#define V_OLD(major, minor, patch) \
V((major), (minor), (patch)-'a'+1)
/** @} */
/** Represetns a version of libevent so old we can't figure out what version
* it is. */
#define LE_OLD V(0,0,0)
/** Represents a version of libevent so weird we can't figure out what version
* it is. */
#define LE_OTHER V(0,0,99)
STATIC void
libevent_logging_callback(int severity, const char *msg);
STATIC le_version_t
tor_decode_libevent_version(const char *v);
STATIC int
le_versions_compatibility(le_version_t v);
#endif
#endif
-12
View File
@@ -10,11 +10,7 @@
#include "util.h"
#ifdef HAVE_EVENT2_EVENT_H
#include <event2/event.h>
#else
#include <event.h>
#endif
#ifdef HAVE_SIGNAL_H
#include <signal.h>
@@ -164,11 +160,7 @@ tor_validate_process_specifier(const char *process_spec,
}
/* XXXX we should use periodic_timer_new() for this stuff */
#ifdef HAVE_EVENT2_EVENT_H
#define PERIODIC_TIMER_FLAGS EV_PERSIST
#else
#define PERIODIC_TIMER_FLAGS (0)
#endif
/* DOCDOC poll_interval_tv */
static struct timeval poll_interval_tv = {15, 0};
@@ -331,10 +323,6 @@ tor_process_monitor_poll_cb(evutil_socket_t unused1, short unused2,
if (its_dead_jim) {
procmon->cb(procmon->cb_arg);
#ifndef HAVE_EVENT2_EVENT_H
} else {
evtimer_add(procmon->e, &poll_interval_tv);
#endif
}
}
#endif
-4
View File
@@ -38,11 +38,7 @@
#include "torlog.h"
#include "util.h"
#ifdef HAVE_EVENT2_EVENT_H
#include <event2/event.h>
#else
#include <event.h>
#endif
struct timeout_cb {
timer_cb_fn_t cb;