Merge remote-tracking branch 'origin/maint-0.2.6' into release-0.2.6

This commit is contained in:
Nick Mathewson 2015-03-18 09:06:21 -04:00
commit bbf304be26
2 changed files with 66 additions and 36 deletions

3
changes/ticket15176 Normal file
View File

@ -0,0 +1,3 @@
o Code simplification and refactoring:
- Refactor main loop to extract the 'loop' part. This makes it easier
to run Tor under Shadow. Closes ticket 15176.

View File

@ -97,6 +97,7 @@ static void second_elapsed_callback(periodic_timer_t *timer, void *args);
static int conn_close_if_marked(int i); static int conn_close_if_marked(int i);
static void connection_start_reading_from_linked_conn(connection_t *conn); static void connection_start_reading_from_linked_conn(connection_t *conn);
static int connection_should_read_from_linked_conn(connection_t *conn); static int connection_should_read_from_linked_conn(connection_t *conn);
static int run_main_loop_until_done(void);
/********* START VARIABLES **********/ /********* START VARIABLES **********/
@ -1955,7 +1956,6 @@ do_hup(void)
int int
do_main_loop(void) do_main_loop(void)
{ {
int loop_result;
time_t now; time_t now;
/* initialize dns resolve map, spawn workers if needed */ /* initialize dns resolve map, spawn workers if needed */
@ -2084,51 +2084,78 @@ do_main_loop(void)
} }
#endif #endif
for (;;) { return run_main_loop_until_done();
if (nt_service_is_stopping()) }
return 0;
/**
* Run the main loop a single time. Return 0 for "exit"; -1 for "exit with
* error", and 1 for "run this again."
*/
static int
run_main_loop_once(void)
{
int loop_result;
if (nt_service_is_stopping())
return 0;
#ifndef _WIN32 #ifndef _WIN32
/* Make it easier to tell whether libevent failure is our fault or not. */ /* Make it easier to tell whether libevent failure is our fault or not. */
errno = 0; errno = 0;
#endif #endif
/* All active linked conns should get their read events activated. */ /* All active linked conns should get their read events activated. */
SMARTLIST_FOREACH(active_linked_connection_lst, connection_t *, conn, SMARTLIST_FOREACH(active_linked_connection_lst, connection_t *, conn,
event_active(conn->read_event, EV_READ, 1)); event_active(conn->read_event, EV_READ, 1));
called_loop_once = smartlist_len(active_linked_connection_lst) ? 1 : 0; called_loop_once = smartlist_len(active_linked_connection_lst) ? 1 : 0;
update_approx_time(time(NULL)); update_approx_time(time(NULL));
/* poll until we have an event, or the second ends, or until we have /* poll until we have an event, or the second ends, or until we have
* some active linked connections to trigger events for. */ * some active linked connections to trigger events for. */
loop_result = event_base_loop(tor_libevent_get_base(), loop_result = event_base_loop(tor_libevent_get_base(),
called_loop_once ? EVLOOP_ONCE : 0); called_loop_once ? EVLOOP_ONCE : 0);
/* let catch() handle things like ^c, and otherwise don't worry about it */ /* let catch() handle things like ^c, and otherwise don't worry about it */
if (loop_result < 0) { if (loop_result < 0) {
int e = tor_socket_errno(-1); int e = tor_socket_errno(-1);
/* let the program survive things like ^z */ /* let the program survive things like ^z */
if (e != EINTR && !ERRNO_IS_EINPROGRESS(e)) { if (e != EINTR && !ERRNO_IS_EINPROGRESS(e)) {
log_err(LD_NET,"libevent call with %s failed: %s [%d]", log_err(LD_NET,"libevent call with %s failed: %s [%d]",
tor_libevent_get_method(), tor_socket_strerror(e), e); tor_libevent_get_method(), tor_socket_strerror(e), e);
return -1;
#ifndef _WIN32
} else if (e == EINVAL) {
log_warn(LD_NET, "EINVAL from libevent: should you upgrade libevent?");
if (got_libevent_error())
return -1; return -1;
#ifndef _WIN32
} else if (e == EINVAL) {
log_warn(LD_NET, "EINVAL from libevent: should you upgrade libevent?");
if (got_libevent_error())
return -1;
#endif #endif
} else { } else {
if (ERRNO_IS_EINPROGRESS(e)) if (ERRNO_IS_EINPROGRESS(e))
log_warn(LD_BUG, log_warn(LD_BUG,
"libevent call returned EINPROGRESS? Please report."); "libevent call returned EINPROGRESS? Please report.");
log_debug(LD_NET,"libevent call interrupted."); log_debug(LD_NET,"libevent call interrupted.");
/* You can't trust the results of this poll(). Go back to the /* You can't trust the results of this poll(). Go back to the
* top of the big for loop. */ * top of the big for loop. */
continue; return 1;
}
} }
} }
return 1;
}
/** Run the run_main_loop_once() function until it declares itself done,
* and return its final return value.
*
* Shadow won't invoke this function, so don't fill it up with things.
*/
static int
run_main_loop_until_done(void)
{
int loop_result = 1;
do {
loop_result = run_main_loop_once();
} while (loop_result == 1);
return loop_result;
} }
#ifndef _WIN32 /* Only called when we're willing to use signals */ #ifndef _WIN32 /* Only called when we're willing to use signals */