aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2012-02-12 22:24:52 -0500
committerNick Mathewson <nickm@torproject.org>2012-02-12 23:30:18 -0500
commitfff511a5e76e82e0aa8af4a665e0d0abb69b7583 (patch)
tree3f9cab169db41bdaf6aad221f799d87318200e2d
parentd7d6da28d4264aa2d018cfe9437117ae6dbefce9 (diff)
downloadtor-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.c18
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;