Remove a 9-function strongly connected component of tor's callgraph.

microdesc_free_() called get_microdesc_cache(), which had the fun
side-effect of potentially reloading the whole cache from disk.
Replace it with a variant that doesn't.
This commit is contained in:
Nick Mathewson
2015-08-10 14:27:23 -04:00
parent def5883bbb
commit 8afbc154f7
2 changed files with 27 additions and 4 deletions
+4
View File
@@ -0,0 +1,4 @@
o Code simplification and refactoring:
- Simplify the microdesc_free() implementation so that it no longer
appears (to code analysis tools) to potentially invoke a huge suite
of other microdesc functions.
+23 -4
View File
@@ -39,8 +39,13 @@ struct microdesc_cache_t {
uint64_t total_len_seen; uint64_t total_len_seen;
/** Total number of microdescriptors we have added to this cache */ /** Total number of microdescriptors we have added to this cache */
unsigned n_seen; unsigned n_seen;
/** True iff we have loaded this cache from disk ever. */
int is_loaded;
}; };
static microdesc_cache_t *get_microdesc_cache_noload(void);
/** Helper: computes a hash of <b>md</b> to place it in a hash table. */ /** Helper: computes a hash of <b>md</b> to place it in a hash table. */
static INLINE unsigned int static INLINE unsigned int
microdesc_hash_(microdesc_t *md) microdesc_hash_(microdesc_t *md)
@@ -112,13 +117,25 @@ static microdesc_cache_t *the_microdesc_cache = NULL;
/** Return a pointer to the microdescriptor cache, loading it if necessary. */ /** Return a pointer to the microdescriptor cache, loading it if necessary. */
microdesc_cache_t * microdesc_cache_t *
get_microdesc_cache(void) get_microdesc_cache(void)
{
microdesc_cache_t *cache = get_microdesc_cache_noload();
if (PREDICT_UNLIKELY(cache->is_loaded == 0)) {
microdesc_cache_reload(cache);
}
return cache;
}
/** Return a pointer to the microdescriptor cache, creating (but not loading)
* it if necessary. */
static microdesc_cache_t *
get_microdesc_cache_noload(void)
{ {
if (PREDICT_UNLIKELY(the_microdesc_cache==NULL)) { if (PREDICT_UNLIKELY(the_microdesc_cache==NULL)) {
microdesc_cache_t *cache = tor_malloc_zero(sizeof(microdesc_cache_t)); microdesc_cache_t *cache = tor_malloc_zero(sizeof(*cache));
tor_malloc_zero(sizeof(microdesc_cache_t));
HT_INIT(microdesc_map, &cache->map); HT_INIT(microdesc_map, &cache->map);
cache->cache_fname = get_datadir_fname("cached-microdescs"); cache->cache_fname = get_datadir_fname("cached-microdescs");
cache->journal_fname = get_datadir_fname("cached-microdescs.new"); cache->journal_fname = get_datadir_fname("cached-microdescs.new");
microdesc_cache_reload(cache);
the_microdesc_cache = cache; the_microdesc_cache = cache;
} }
return the_microdesc_cache; return the_microdesc_cache;
@@ -353,6 +370,8 @@ microdesc_cache_reload(microdesc_cache_t *cache)
microdesc_cache_clear(cache); microdesc_cache_clear(cache);
cache->is_loaded = 1;
mm = cache->cache_content = tor_mmap_file(cache->cache_fname); mm = cache->cache_content = tor_mmap_file(cache->cache_fname);
if (mm) { if (mm) {
added = microdescs_add_to_cache(cache, mm->data, mm->data+mm->size, added = microdescs_add_to_cache(cache, mm->data, mm->data+mm->size,
@@ -697,7 +716,7 @@ microdesc_free_(microdesc_t *md, const char *fname, int lineno)
/* Make sure that the microdesc was really removed from the appropriate data /* Make sure that the microdesc was really removed from the appropriate data
structures. */ structures. */
if (md->held_in_map) { if (md->held_in_map) {
microdesc_cache_t *cache = get_microdesc_cache(); microdesc_cache_t *cache = get_microdesc_cache_noload();
microdesc_t *md2 = HT_FIND(microdesc_map, &cache->map, md); microdesc_t *md2 = HT_FIND(microdesc_map, &cache->map, md);
if (md2 == md) { if (md2 == md) {
log_warn(LD_BUG, "microdesc_free() called from %s:%d, but md was still " log_warn(LD_BUG, "microdesc_free() called from %s:%d, but md was still "
@@ -710,7 +729,7 @@ microdesc_free_(microdesc_t *md, const char *fname, int lineno)
tor_fragile_assert(); tor_fragile_assert();
} }
if (md->held_by_nodes) { if (md->held_by_nodes) {
microdesc_cache_t *cache = get_microdesc_cache(); microdesc_cache_t *cache = get_microdesc_cache_noload();
int found=0; int found=0;
const smartlist_t *nodes = nodelist_get_list(); const smartlist_t *nodes = nodelist_get_list();
const int ht_badness = HT_REP_IS_BAD_(microdesc_map, &cache->map); const int ht_badness = HT_REP_IS_BAD_(microdesc_map, &cache->map);