|
@@ -450,10 +450,16 @@ circuit_count_pending_on_channel(channel_t *chan)
|
|
|
void
|
|
|
circuit_close_all_marked(void)
|
|
|
{
|
|
|
- circuit_t *circ, *tmp;
|
|
|
- TOR_LIST_FOREACH_SAFE(circ, &global_circuitlist, head, tmp)
|
|
|
- if (circ->marked_for_close)
|
|
|
+ smartlist_t *lst = circuit_get_global_list();
|
|
|
+ SMARTLIST_FOREACH_BEGIN(lst, circuit_t *, circ) {
|
|
|
+
|
|
|
+ circ->global_circuitlist_idx = circ_sl_idx;
|
|
|
+ if (circ->marked_for_close) {
|
|
|
+ circ->global_circuitlist_idx = -1;
|
|
|
circuit_free(circ);
|
|
|
+ SMARTLIST_DEL_CURRENT(lst, circ);
|
|
|
+ }
|
|
|
+ } SMARTLIST_FOREACH_END(circ);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -679,7 +685,8 @@ init_circuit_base(circuit_t *circ)
|
|
|
circ->deliver_window = CIRCWINDOW_START;
|
|
|
cell_queue_init(&circ->n_chan_cells);
|
|
|
|
|
|
- TOR_LIST_INSERT_HEAD(&global_circuitlist, circ, head);
|
|
|
+ smartlist_add(circuit_get_global_list(), circ);
|
|
|
+ circ->global_circuitlist_idx = smartlist_len(circuit_get_global_list()) - 1;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -800,7 +807,16 @@ circuit_free(circuit_t *circ)
|
|
|
extend_info_free(circ->n_hop);
|
|
|
tor_free(circ->n_chan_create_cell);
|
|
|
|
|
|
- TOR_LIST_REMOVE(circ, head);
|
|
|
+ if (circ->global_circuitlist_idx != -1) {
|
|
|
+ int idx = circ->global_circuitlist_idx;
|
|
|
+ circuit_t *c2 = smartlist_get(global_circuitlist, idx);
|
|
|
+ tor_assert(c2 == circ);
|
|
|
+ smartlist_del(global_circuitlist, idx);
|
|
|
+ if (idx < smartlist_len(global_circuitlist)) {
|
|
|
+ c2 = smartlist_get(global_circuitlist, idx);
|
|
|
+ c2->global_circuitlist_idx = idx;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
|
|
|
circuit_set_n_circid_chan(circ, 0, NULL);
|
|
@@ -842,9 +858,9 @@ circuit_clear_cpath(origin_circuit_t *circ)
|
|
|
void
|
|
|
circuit_free_all(void)
|
|
|
{
|
|
|
- circuit_t *tmp, *tmp2;
|
|
|
+ smartlist_t *lst = circuit_get_global_list();
|
|
|
|
|
|
- TOR_LIST_FOREACH_SAFE(tmp, &global_circuitlist, head, tmp2) {
|
|
|
+ SMARTLIST_FOREACH_BEGIN(lst, circuit_t *, tmp) {
|
|
|
if (! CIRCUIT_IS_ORIGIN(tmp)) {
|
|
|
or_circuit_t *or_circ = TO_OR_CIRCUIT(tmp);
|
|
|
while (or_circ->resolving_streams) {
|
|
@@ -854,8 +870,13 @@ circuit_free_all(void)
|
|
|
or_circ->resolving_streams = next_conn;
|
|
|
}
|
|
|
}
|
|
|
+ tmp->global_circuitlist_idx = -1;
|
|
|
circuit_free(tmp);
|
|
|
- }
|
|
|
+ SMARTLIST_DEL_CURRENT(lst, tmp);
|
|
|
+ } SMARTLIST_FOREACH_END(tmp);
|
|
|
+
|
|
|
+ smartlist_free(lst);
|
|
|
+ global_circuitlist = NULL;
|
|
|
|
|
|
smartlist_free(circuits_pending_chans);
|
|
|
circuits_pending_chans = NULL;
|
|
@@ -1262,14 +1283,17 @@ origin_circuit_t *
|
|
|
circuit_get_next_by_pk_and_purpose(origin_circuit_t *start,
|
|
|
const char *digest, uint8_t purpose)
|
|
|
{
|
|
|
- circuit_t *circ;
|
|
|
+ int idx;
|
|
|
+ smartlist_t *lst = circuit_get_global_list();
|
|
|
tor_assert(CIRCUIT_PURPOSE_IS_ORIGIN(purpose));
|
|
|
if (start == NULL)
|
|
|
- circ = TOR_LIST_FIRST(&global_circuitlist);
|
|
|
+ idx = 0;
|
|
|
else
|
|
|
- circ = TOR_LIST_NEXT(TO_CIRCUIT(start), head);
|
|
|
+ idx = TO_CIRCUIT(start)->global_circuitlist_idx + 1;
|
|
|
+
|
|
|
+ for ( ; idx < smartlist_len(lst); ++idx) {
|
|
|
+ circuit_t *circ = smartlist_get(lst, idx);
|
|
|
|
|
|
- for ( ; circ; circ = TOR_LIST_NEXT(circ, head)) {
|
|
|
if (circ->marked_for_close)
|
|
|
continue;
|
|
|
if (circ->purpose != purpose)
|