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 /src/or | |
parent | d7d6da28d4264aa2d018cfe9437117ae6dbefce9 (diff) | |
download | tor-fff511a5e76e82e0aa8af4a665e0d0abb69b7583.tar.gz tor-fff511a5e76e82e0aa8af4a665e0d0abb69b7583.zip |
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.
Diffstat (limited to 'src/or')
-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 3d8e11dd66..daa62b5ae7 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; |