diff options
author | Nick Mathewson <nickm@torproject.org> | 2012-02-12 22:24:52 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2012-02-12 23:30:18 -0500 |
commit | fff511a5e76e82e0aa8af4a665e0d0abb69b7583 (patch) | |
tree | 3f9cab169db41bdaf6aad221f799d87318200e2d | |
parent | d7d6da28d4264aa2d018cfe9437117ae6dbefce9 (diff) | |
download | tor-fff511a5e76e82e0aa8af4a665e0d0abb69b7583.tar tor-fff511a5e76e82e0aa8af4a665e0d0abb69b7583.tar.gz |
Don't smartlist_remove a managed proxy from a list we're iterating over.
In some cases, we solve this by doing a SMARTLIST_DEL_CURRENT before
calling managed_proxy_destroy. But for a trickier one, we just make a
copy of the list before iterating over it, so that changes to the
manage proxy list don't hurt our iteration.
This could be related to bug 5084.
-rw-r--r-- | src/or/transports.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/src/or/transports.c b/src/or/transports.c index 3d8e11dd6..daa62b5ae 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -316,9 +316,16 @@ launch_managed_proxy(managed_proxy_t *mp) void pt_configure_remaining_proxies(void) { + smartlist_t *tmp = smartlist_new(); + log_debug(LD_CONFIG, "Configuring remaining managed proxies (%d)!", unconfigured_proxies_n); - SMARTLIST_FOREACH_BEGIN(managed_proxy_list, managed_proxy_t *, mp) { + + /* Iterate over tmp, not managed_proxy_list, since configure_proxy can + * remove elements from managed_proxy_list. */ + smartlist_add_all(tmp, managed_proxy_list); + + SMARTLIST_FOREACH_BEGIN(tmp, managed_proxy_t *, mp) { tor_assert(mp->conf_state != PT_PROTO_BROKEN || mp->conf_state != PT_PROTO_FAILED_LAUNCH); @@ -347,6 +354,8 @@ pt_configure_remaining_proxies(void) configure_proxy(mp); } SMARTLIST_FOREACH_END(mp); + + smartlist_free(tmp); } #ifdef _WIN32 @@ -1196,6 +1205,7 @@ pt_prepare_proxy_list_for_config_read(void) SMARTLIST_FOREACH_BEGIN(managed_proxy_list, managed_proxy_t *, mp) { /* Destroy unconfigured proxies. */ if (mp->conf_state != PT_PROTO_COMPLETED) { + SMARTLIST_DEL_CURRENT(managed_proxy_list, mp); managed_proxy_destroy(mp, 1); unconfigured_proxies_n--; continue; @@ -1239,8 +1249,10 @@ pt_free_all(void) transports and it's the duty of the circuitbuild.c subsystem to free them. Otherwise, it hasn't registered its transports yet and we should free them here. */ - SMARTLIST_FOREACH(managed_proxy_list, managed_proxy_t *, mp, - managed_proxy_destroy(mp, 1)); + SMARTLIST_FOREACH(managed_proxy_list, managed_proxy_t *, mp, { + SMARTLIST_DEL_CURRENT(managed_proxy_list, mp); + managed_proxy_destroy(mp, 1); + }); smartlist_free(managed_proxy_list); managed_proxy_list=NULL; |