diff options
author | Nick Mathewson <nickm@torproject.org> | 2013-09-09 13:48:44 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2014-03-14 11:57:51 -0400 |
commit | 1a74360c2dd5c197e2dfc28b37961c77bb7792f1 (patch) | |
tree | d1e856ff67b9dcf2a97fabaaea5fc599566a62d6 /src/or/circuitlist.c | |
parent | 102bb1c04f5cb4fb3eae7f41f80660e47c64ceb6 (diff) | |
download | tor-1a74360c2dd5c197e2dfc28b37961c77bb7792f1.tar.gz tor-1a74360c2dd5c197e2dfc28b37961c77bb7792f1.zip |
Test code for implementation of faster circuit_unlink_all_from_channel
This contains the obvious implementation using the circuitmux data
structure. It also runs the old (slow) algorithm and compares
the results of the two to make sure that they're the same.
Needs review and testing.
Diffstat (limited to 'src/or/circuitlist.c')
-rw-r--r-- | src/or/circuitlist.c | 61 |
1 files changed, 57 insertions, 4 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index b2eb730c8c..0015a680cf 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -1144,12 +1144,58 @@ void circuit_unlink_all_from_channel(channel_t *chan, int reason) { circuit_t *circ; + smartlist_t *detached = smartlist_new(); - channel_unlink_all_circuits(chan); +#define DEBUG_CIRCUIT_UNLINK_ALL - TOR_LIST_FOREACH(circ, &global_circuitlist, head) { + channel_unlink_all_circuits(chan, detached); + +#ifdef DEBUG_CIRCUIT_UNLINK_ALL + { + smartlist_t *detached_2 = smartlist_new(); + int mismatch = 0, badlen = 0; + + TOR_LIST_FOREACH(circ, &global_circuitlist, head) { + if (circ->n_chan == chan || + (!CIRCUIT_IS_ORIGIN(circ) && + TO_OR_CIRCUIT(circ)->p_chan == chan)) { + smartlist_add(detached_2, circ); + } + } + + if (smartlist_len(detached) != smartlist_len(detached_2)) { + log_warn(LD_BUG, "List of detached circuits had the wrong length! " + "(got %d, should have gotten %d)", + (int)smartlist_len(detached), + (int)smartlist_len(detached_2)); + badlen = 1; + } + smartlist_sort_pointers(detached); + smartlist_sort_pointers(detached_2); + + SMARTLIST_FOREACH(detached, circuit_t *, c, + if (c != smartlist_get(detached_2, c_sl_idx)) + mismatch = 1; + ); + + if (mismatch) + log_warn(LD_BUG, "Mismatch in list of detached circuits."); + + if (badlen || mismatch) { + smartlist_free(detached); + detached = detached_2; + } else { + log_notice(LD_CIRC, "List of %d circuits was as expected.", + (int)smartlist_len(detached)); + smartlist_free(detached_2); + } + } +#endif + + SMARTLIST_FOREACH_BEGIN(detached, circuit_t *, circ) { int mark = 0; if (circ->n_chan == chan) { + circuit_set_n_circid_chan(circ, 0, NULL); mark = 1; @@ -1165,9 +1211,16 @@ circuit_unlink_all_from_channel(channel_t *chan, int reason) mark = 1; } } - if (mark && !circ->marked_for_close) + if (!mark) { + log_warn(LD_BUG, "Circuit on detached list which I had no reason " + "to mark"); + continue; + } + if (!circ->marked_for_close) circuit_mark_for_close(circ, reason); - } + } SMARTLIST_FOREACH_END(circ); + + smartlist_free(detached); } /** Return a circ such that |