summaryrefslogtreecommitdiff
path: root/src/or
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 /src/or
parentd7d6da28d4264aa2d018cfe9437117ae6dbefce9 (diff)
downloadtor-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.c18
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;