Add a new option to enable/disable IOCP support

This commit is contained in:
Nick Mathewson 2010-09-28 14:01:45 -04:00
parent d6e255edbd
commit c612ddee17
6 changed files with 46 additions and 7 deletions

View File

@ -6,4 +6,7 @@
flag. Using this feature will make our networking code more flexible, flag. Using this feature will make our networking code more flexible,
lets us stack layers on each other, and let us use more efficient lets us stack layers on each other, and let us use more efficient
zero-copy transports where available. zero-copy transports where available.
- As an experimental feature, when using the "bufferevents" buffered
IO backend, Tor can try to use Windows's IOCP networking API. This
is off by default. To turn it on, add "DisableIOCP 0" to your torrc.

View File

@ -397,6 +397,11 @@ Other options can be specified either on the command-line (--option
networkstatus. This is an advanced option; you generally shouldn't have networkstatus. This is an advanced option; you generally shouldn't have
to mess with it. (Default: not set.) to mess with it. (Default: not set.)
**DisableIOCP** **0**|**1**::
If Tor was built to use the Libevent's "bufferevents" networking code
and you're running on Windows, setting this option to 1 will tell Libevent
not to use the Windows IOCP networking API. (Default: 1)
CLIENT OPTIONS CLIENT OPTIONS
-------------- --------------

View File

@ -159,7 +159,7 @@ struct event_base *the_event_base = NULL;
/** Initialize the Libevent library and set up the event base. */ /** Initialize the Libevent library and set up the event base. */
void void
tor_libevent_initialize(void) tor_libevent_initialize(tor_libevent_cfg *torcfg)
{ {
tor_assert(the_event_base == NULL); tor_assert(the_event_base == NULL);
@ -171,7 +171,21 @@ tor_libevent_initialize(void)
#endif #endif
#ifdef HAVE_EVENT2_EVENT_H #ifdef HAVE_EVENT2_EVENT_H
the_event_base = event_base_new(); {
struct event_config *cfg = event_config_new();
#if defined(MS_WINDOWS) && defined(USE_BUFFEREVENTS)
if (! torcfg->disable_iocp)
event_config_set_flag(cfg, EVENT_BASE_FLAG_STARTUP_IOCP);
#endif
#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
the_event_base = event_base_new_with_config(cfg);
}
#else #else
the_event_base = event_init(); the_event_base = event_init();
#endif #endif

View File

@ -56,7 +56,12 @@ struct timeval;
int tor_event_base_loopexit(struct event_base *base, struct timeval *tv); int tor_event_base_loopexit(struct event_base *base, struct timeval *tv);
#endif #endif
void tor_libevent_initialize(void); typedef struct tor_libevent_cfg {
int disable_iocp;
int num_cpus;
} tor_libevent_cfg;
void tor_libevent_initialize(tor_libevent_cfg *cfg);
struct event_base *tor_libevent_get_base(void); struct event_base *tor_libevent_get_base(void);
const char *tor_libevent_get_method(void); const char *tor_libevent_get_method(void);
void tor_check_libevent_version(const char *m, int server, void tor_check_libevent_version(const char *m, int server,

View File

@ -224,6 +224,7 @@ static config_var_t _option_vars[] = {
V(DirReqStatistics, BOOL, "0"), V(DirReqStatistics, BOOL, "0"),
VAR("DirServer", LINELIST, DirServers, NULL), VAR("DirServer", LINELIST, DirServers, NULL),
V(DisableAllSwap, BOOL, "0"), V(DisableAllSwap, BOOL, "0"),
V(DisableIOCP, BOOL, "1"),
V(DNSPort, UINT, "0"), V(DNSPort, UINT, "0"),
V(DNSListenAddress, LINELIST, NULL), V(DNSListenAddress, LINELIST, NULL),
V(DownloadExtraInfo, BOOL, "0"), V(DownloadExtraInfo, BOOL, "0"),
@ -554,7 +555,7 @@ static int is_listening_on_low_port(uint16_t port_option,
static uint64_t config_parse_memunit(const char *s, int *ok); static uint64_t config_parse_memunit(const char *s, int *ok);
static int config_parse_interval(const char *s, int *ok); static int config_parse_interval(const char *s, int *ok);
static void init_libevent(void); static void init_libevent(const or_options_t *options);
static int opt_streq(const char *s1, const char *s2); static int opt_streq(const char *s1, const char *s2);
/** Magic value for or_options_t. */ /** Magic value for or_options_t. */
@ -955,7 +956,7 @@ options_act_reversible(or_options_t *old_options, char **msg)
/* Set up libevent. (We need to do this before we can register the /* Set up libevent. (We need to do this before we can register the
* listeners as listeners.) */ * listeners as listeners.) */
if (running_tor && !libevent_initialized) { if (running_tor && !libevent_initialized) {
init_libevent(); init_libevent(options);
libevent_initialized = 1; libevent_initialized = 1;
} }
@ -4895,9 +4896,12 @@ config_parse_interval(const char *s, int *ok)
* Initialize the libevent library. * Initialize the libevent library.
*/ */
static void static void
init_libevent(void) init_libevent(const or_options_t *options)
{ {
const char *badness=NULL; const char *badness=NULL;
tor_libevent_cfg cfg;
tor_assert(options);
configure_libevent_logging(); configure_libevent_logging();
/* If the kernel complains that some method (say, epoll) doesn't /* If the kernel complains that some method (say, epoll) doesn't
@ -4907,7 +4911,11 @@ init_libevent(void)
tor_check_libevent_header_compatibility(); tor_check_libevent_header_compatibility();
tor_libevent_initialize(); memset(&cfg, 0, sizeof(cfg));
cfg.disable_iocp = options->DisableIOCP;
cfg.num_cpus = options->NumCpus;
tor_libevent_initialize(&cfg);
suppress_libevent_log_msg(NULL); suppress_libevent_log_msg(NULL);

View File

@ -2892,6 +2892,10 @@ typedef struct {
*/ */
double CircuitPriorityHalflife; double CircuitPriorityHalflife;
/** If true, do not enable IOCP on windows with bufferevents, even if
* we think we could. */
int DisableIOCP;
} or_options_t; } or_options_t;
/** Persistent state for an onion router, as saved to disk. */ /** Persistent state for an onion router, as saved to disk. */