[tor-commits] [tor/master] Don't smartlist_remove a managed proxy from a list we're iterating over.

nickm at torproject.org nickm at torproject.org
Mon Feb 13 04:29:41 UTC 2012


commit fff511a5e76e82e0aa8af4a665e0d0abb69b7583
Author: Nick Mathewson <nickm at torproject.org>
Date:   Sun Feb 12 22:24:52 2012 -0500

    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.
---
 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 3d8e11d..daa62b5 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;





More information about the tor-commits mailing list