static void replysock_readable_cb(tor_socket_t sock, short what, void *arg) { threadpool_t *tp = arg; replyqueue_t *rq = threadpool_get_replyqueue(tp); int old_r = n_received; (void) sock; (void) what; replyqueue_process(rq); if (old_r == n_received) return; if (opt_verbose) { printf("%d / %d", n_received, n_sent); if (opt_n_cancel) printf(" (%d cancelled, %d uncancellable)", n_successful_cancel, n_failed_cancel); puts(""); } #ifdef TRACK_RESPONSES tor_mutex_acquire(&bitmap_mutex); for (i = 0; i < opt_n_items; ++i) { if (bitarray_is_set(received, i)) putc('o', stdout); else if (bitarray_is_set(handled, i)) putc('!', stdout); else putc('.', stdout); } puts(""); tor_mutex_release(&bitmap_mutex); #endif if (n_sent - (n_received+n_successful_cancel) < opt_n_lowwater) { int n_to_send = n_received + opt_n_inflight - n_sent; if (n_to_send > opt_n_items - n_sent) n_to_send = opt_n_items - n_sent; add_n_work_items(tp, n_to_send); } if (shutting_down == 0 && n_received+n_successful_cancel == n_sent && n_sent >= opt_n_items) { shutting_down = 1; threadpool_queue_update(tp, NULL, workqueue_do_shutdown, NULL, NULL); // Anything we add after starting the shutdown must not be executed. threadpool_queue_work(tp, workqueue_shutdown_error, handle_reply_shutdown, NULL); { struct timeval limit = { 2, 0 }; tor_event_base_loopexit(tor_libevent_get_base(), &limit); } } }
static void test_pick_circid(void *arg) { bitarray_t *ba = NULL; channel_t *chan1, *chan2; circid_t circid; int i; (void) arg; chan1 = tor_malloc_zero(sizeof(channel_t)); chan2 = tor_malloc_zero(sizeof(channel_t)); chan2->wide_circ_ids = 1; chan1->circ_id_type = CIRC_ID_TYPE_NEITHER; tt_int_op(0, ==, get_unique_circ_id_by_chan(chan1)); /* Basic tests, with no collisions */ chan1->circ_id_type = CIRC_ID_TYPE_LOWER; for (i = 0; i < 50; ++i) { circid = get_unique_circ_id_by_chan(chan1); tt_uint_op(0, <, circid); tt_uint_op(circid, <, (1<<15)); } chan1->circ_id_type = CIRC_ID_TYPE_HIGHER; for (i = 0; i < 50; ++i) { circid = get_unique_circ_id_by_chan(chan1); tt_uint_op((1<<15), <, circid); tt_uint_op(circid, <, (1<<16)); } chan2->circ_id_type = CIRC_ID_TYPE_LOWER; for (i = 0; i < 50; ++i) { circid = get_unique_circ_id_by_chan(chan2); tt_uint_op(0, <, circid); tt_uint_op(circid, <, (1u<<31)); } chan2->circ_id_type = CIRC_ID_TYPE_HIGHER; for (i = 0; i < 50; ++i) { circid = get_unique_circ_id_by_chan(chan2); tt_uint_op((1u<<31), <, circid); } /* Now make sure that we can behave well when we are full up on circuits */ chan1->circ_id_type = CIRC_ID_TYPE_LOWER; chan2->circ_id_type = CIRC_ID_TYPE_LOWER; chan1->wide_circ_ids = chan2->wide_circ_ids = 0; ba = bitarray_init_zero((1<<15)); for (i = 0; i < (1<<15); ++i) { circid = get_unique_circ_id_by_chan(chan1); if (circid == 0) { tt_int_op(i, >, (1<<14)); break; } tt_uint_op(circid, <, (1<<15)); tt_assert(! bitarray_is_set(ba, circid)); bitarray_set(ba, circid); channel_mark_circid_unusable(chan1, circid); }
/** Run unit tests for bitarray code */ static void test_container_bitarray(void *arg) { bitarray_t *ba = NULL; int i, j, ok=1; (void)arg; ba = bitarray_init_zero(1); tt_assert(ba); tt_assert(! bitarray_is_set(ba, 0)); bitarray_set(ba, 0); tt_assert(bitarray_is_set(ba, 0)); bitarray_clear(ba, 0); tt_assert(! bitarray_is_set(ba, 0)); bitarray_free(ba); ba = bitarray_init_zero(1023); for (i = 1; i < 64; ) { for (j = 0; j < 1023; ++j) { if (j % i) bitarray_set(ba, j); else bitarray_clear(ba, j); } for (j = 0; j < 1023; ++j) { if (!bool_eq(bitarray_is_set(ba, j), j%i)) ok = 0; } tt_assert(ok); if (i < 7) ++i; else if (i == 28) i = 32; else i += 7; } done: if (ba) bitarray_free(ba); }
static void handle_reply(void *arg) { #ifdef TRACK_RESPONSES rsa_work_t *rw = arg; /* Naughty cast, but only looking at serial. */ tor_assert(! bitarray_is_set(received, rw->serial)); bitarray_set(received,rw->serial); #endif tor_free(arg); ++n_received; }
/** Run unit tests for bitarray code */ static void test_container_bitarray(void *unused) { bitarray_t *ba = NULL; int i, j; ba = bitarray_init_zero(1); tt_assert(ba); tt_assert(! bitarray_is_set(ba, 0)); bitarray_set(ba, 0); tt_assert(bitarray_is_set(ba, 0)); bitarray_clear(ba, 0); tt_assert(! bitarray_is_set(ba, 0)); bitarray_free(ba); ba = bitarray_init_zero(1023); for (i = 1; i < 64; ) { for (j = 0; j < 1023; ++j) { if (j % i) bitarray_set(ba, j); else bitarray_clear(ba, j); } for (j = 0; j < 1023; ++j) { tt_bool_op(bitarray_is_set(ba, j), ==, j%i); } if (i < 7) ++i; else if (i == 28) i = 32; else i += 7; } end: if (ba) bitarray_free(ba); }
static void mark_handled(int serial) { #ifdef TRACK_RESPONSES tor_mutex_acquire(&bitmap_mutex); tor_assert(serial < handled_len); tor_assert(! bitarray_is_set(handled, serial)); bitarray_set(handled, serial); tor_mutex_release(&bitmap_mutex); #else (void)serial; #endif }
/** * Take a list of uint16_t *, and remove every port in the list from the * current list of predicted ports. */ void rep_hist_remove_predicted_ports(const smartlist_t *rmv_ports) { /* Let's do this on O(N), not O(N^2). */ bitarray_t *remove_ports = bitarray_init_zero(UINT16_MAX); SMARTLIST_FOREACH(rmv_ports, const uint16_t *, p, bitarray_set(remove_ports, *p)); SMARTLIST_FOREACH_BEGIN(predicted_ports_list, predicted_port_t *, pp) { if (bitarray_is_set(remove_ports, pp->port)) { tor_free(pp); predicted_ports_total_alloc -= sizeof(*pp); SMARTLIST_DEL_CURRENT(predicted_ports_list, pp); } } SMARTLIST_FOREACH_END(pp); bitarray_free(remove_ports); }