/* * Attempt to insert a sapgss_OID corresponding to the gss_OID loc into the * cache. If the OID can now be found in the cache (whether we put it there * or it was already there due to some other thread), return 0, * else return errno from the failed malloc. */ static int cache_insert(gss_OID loc) { sapgss_OID s, *p; size_t len; lock_cache(); if (cache_lookup_locked(loc) != NULL) { unlock_cache(); return 0; } len = 0; if (oid_cache != NULL) for(len = 0; oid_cache[len] != NULL; ++len); assert(len < SIZE_T_MAX / sizeof(sapgss_OID) - 3); p = realloc(oid_cache, (len + 2) * sizeof(sapgss_OID)); if (p == NULL) { unlock_cache(); return ENOMEM; } else if (p != oid_cache) { /* It worked, put it in place. */ oid_cache = p; } /* Copy the OID into new storage */ s = oid_cache[len] = malloc(sizeof(*s)); if (s == NULL) { /* The failed allocation did the NULL-termination already. */ return errno; } s->elements = malloc(loc->length); if (s->elements == NULL) { free(s); oid_cache[len] = NULL; return ENOMEM; } memcpy(s->elements, loc->elements, loc->length); s->length = loc->length; /* terminate the list */ oid_cache[len+1] = NULL; unlock_cache(); return 0; }
static FcCacheSkip * FcCacheFindByAddr (void *object) { FcCacheSkip *ret; lock_cache (); ret = FcCacheFindByAddrUnlocked (object); unlock_cache (); return ret; }
static FcCache * FcCacheFindByStat (struct stat *cache_stat) { FcCacheSkip *s; lock_cache (); for (s = fcCacheChains[0]; s; s = s->next[0]) if (s->cache_dev == cache_stat->st_dev && s->cache_ino == cache_stat->st_ino && s->cache_mtime == cache_stat->st_mtime) { FcRefInc (&s->ref); unlock_cache (); return s->cache; } unlock_cache (); return NULL; }
static sapgss_OID cache_lookup(gss_OID loc) { sapgss_OID o; lock_cache(); o = cache_lookup_locked(loc); unlock_cache(); return o; }
h2o_cache_ref_t *h2o_cache_fetch(h2o_cache_t *cache, uint64_t now, h2o_iovec_t key, h2o_cache_hashcode_t keyhash) { h2o_cache_ref_t search_key, *ref; khiter_t iter; int64_t timeleft; if (keyhash == 0) keyhash = h2o_cache_calchash(key.base, key.len); search_key.key = key; search_key.keyhash = keyhash; lock_cache(cache); purge(cache, now); if ((iter = kh_get(cache, cache->table, &search_key)) == kh_end(cache->table)) goto NotFound; /* found */ ref = kh_key(cache->table, iter); timeleft = get_timeleft(cache, ref, now); if (timeleft < 0) goto NotFound; if ((cache->flags & H2O_CACHE_FLAG_EARLY_UPDATE) != 0 && timeleft < 10 && !ref->_requested_early_update) { ref->_requested_early_update = 1; goto NotFound; } /* move the entry to the top of LRU */ h2o_linklist_unlink(&ref->_lru_link); h2o_linklist_insert(&cache->lru, &ref->_lru_link); __sync_fetch_and_add(&ref->_refcnt, 1); /* unlock and return the found entry */ unlock_cache(cache); return ref; NotFound: unlock_cache(cache); return NULL; }
static FcCache * FcCacheFindByStat (struct stat *cache_stat) { FcCacheSkip *s; lock_cache (); for (s = fcCacheChains[0]; s; s = s->next[0]) if (s->cache_dev == cache_stat->st_dev && s->cache_ino == cache_stat->st_ino && s->cache_mtime == cache_stat->st_mtime) { #ifdef HAVE_STRUCT_STAT_ST_MTIM if (s->cache_mtime != cache_stat->st_mtim.tv_nsec) continue; #endif FcRefInc (&s->ref); unlock_cache (); return s->cache; } unlock_cache (); return NULL; }
void h2o_cache_clear(h2o_cache_t *cache) { lock_cache(cache); while (!h2o_linklist_is_empty(&cache->lru)) { h2o_cache_ref_t *ref = H2O_STRUCT_FROM_MEMBER(h2o_cache_ref_t, _lru_link, cache->lru.next); erase_ref(cache, kh_get(cache, cache->table, ref), 0); } assert(h2o_linklist_is_linked(&cache->age)); assert(kh_size(cache->table) == 0); assert(cache->size == 0); unlock_cache(cache); }
void FcCacheObjectDereference (void *object) { FcCacheSkip *skip; lock_cache (); skip = FcCacheFindByAddrUnlocked (object); if (skip) { if (FcRefDec (&skip->ref) == 1) FcDirCacheDisposeUnlocked (skip->cache); } unlock_cache (); }
/*========================================================== * annotate_with_supplemental -- Expand any references that have REFNs * This converts, eg, "@S25@" to "<1850.Census>" * Used for editing *========================================================*/ void annotate_with_supplemental (NODE node, RFMT rfmt) { BOOLEAN expand_refns = (getlloptint("ExpandRefnsDuringEdit", 0) > 0); BOOLEAN annotate_pointers = (getlloptint("AnnotatePointers", 0) > 0); NODE child=0; CACHEEL cel = node->n_cel; struct tag_node_iter nodeit; if (cel) lock_cache(cel); /* ensure node doesn't fall out of cache */ /* annotate all descendant nodes */ begin_node_it(node, &nodeit); while ((child = next_node_it_ptr(&nodeit)) != NULL) { annotate_node(child, expand_refns, annotate_pointers, rfmt); } if (cel) unlock_cache(cel); }
void h2o_cache_delete(h2o_cache_t *cache, uint64_t now, h2o_iovec_t key, h2o_cache_hashcode_t keyhash) { h2o_cache_ref_t search_key; khiter_t iter; if (keyhash == 0) keyhash = h2o_cache_calchash(key.base, key.len); search_key.key = key; search_key.keyhash = keyhash; lock_cache(cache); purge(cache, now); if ((iter = kh_get(cache, cache->table, &search_key)) != kh_end(cache->table)) erase_ref(cache, iter, 0); unlock_cache(cache); }
/*=================================== * find_xref -- Search node for a cross-reference key * 2001/01/21, Perry Rapp *=================================*/ static BOOLEAN find_xref (CNSTRING key, NODE node, CNSTRING tag1, CNSTRING tag2) { NODE node2; CACHEEL ncel2; BOOLEAN found=FALSE; ncel2 = node_to_cacheel_old(node); lock_cache(ncel2); for (node2 = nchild(node); node2; node2 = nsibling(node2)) { if (eqstr(tag1, ntag(node2)) || (tag2 && eqstr(tag2, ntag(node2)))) { STRING key2 = rmvat(nval(node2)); if (key2 && eqstr(key, key2)) { found = TRUE; goto exit_find; } } } exit_find: unlock_cache(ncel2); return found; }
/*===================================== * check_fam -- check family record * and record any records needing fixing * in tofix list *===================================*/ static BOOLEAN check_fam (CNSTRING key, RECORD rec) { static char prevkey[MAXKEYWIDTH+1]=""; CACHEEL fcel1=0; RECORD recx=0; if (eqstr(key, prevkey)) { report_error(ERR_DUPFAM, _("Duplicate family for %s"), key); } fcel1 = fam_to_cacheel(rec); lock_cache(fcel1); recx = get_record_for_cel(fcel1); ASSERT(todo.pass == 1); process_fam(recx); unlock_cache(fcel1); check_pointers(key, rec); append_indiseq_null(seq_fams, strsave(key), NULL, TRUE, TRUE); return TRUE; }
/*===================================== * check_indi -- check indi record * and record any records needing fixing * in tofix list *===================================*/ static BOOLEAN check_indi (CNSTRING key, RECORD rec) { static char prevkey[MAXKEYWIDTH+1]; CACHEEL icel1=0; RECORD recx=0; if (eqstr(key, prevkey)) { report_error(ERR_DUPINDI, _("Duplicate individual for %s"), key); } icel1 = indi_to_cacheel(rec); lock_cache(icel1); recx = get_record_for_cel(icel1); ASSERT(todo.pass == 1); process_indi(recx); unlock_cache(icel1); check_pointers(key, rec); append_indiseq_null(seq_indis, strsave(key), NULL, TRUE, TRUE); release_record(recx); return TRUE; }
int h2o_cache_set(h2o_cache_t *cache, uint64_t now, h2o_iovec_t key, h2o_cache_hashcode_t keyhash, h2o_iovec_t value) { h2o_cache_ref_t *newref; khiter_t iter; int existed; if (keyhash == 0) keyhash = h2o_cache_calchash(key.base, key.len); /* create newref */ newref = h2o_mem_alloc(sizeof(*newref)); *newref = (h2o_cache_ref_t){h2o_strdup(NULL, key.base, key.len), keyhash, now, value, 0, {}, {}, 1}; lock_cache(cache); /* set or replace the named value */ iter = kh_get(cache, cache->table, newref); if (iter != kh_end(cache->table)) { erase_ref(cache, iter, 1); kh_key(cache->table, iter) = newref; existed = 1; } else { int unused; kh_put(cache, cache->table, newref, &unused); existed = 0; } h2o_linklist_insert(&cache->lru, &newref->_lru_link); h2o_linklist_insert(&cache->age, &newref->_age_link); cache->size += newref->value.len; purge(cache, now); unlock_cache(cache); return existed; }
/*========================================================== * resolve_refn_links -- Resolve and check all links in node tree * This converts, eg, "<1850.Census>" to "@S25@" *========================================================*/ INT resolve_refn_links (NODE node) { INT unresolved = 0; BOOLEAN annotate_pointers = (getlloptint("AnnotatePointers", 0) > 0); NODE child=0; CACHEEL cel = node ? node->n_cel: 0; struct tag_node_iter nodeit; if (!node) return 0; if (cel) lock_cache(cel); /* ensure node doesn't fall out of cache */ /* resolve all descendant nodes */ begin_node_it(node, &nodeit); while ((child = next_node_it_ptr(&nodeit)) != NULL) { if (!resolve_node(child, annotate_pointers)) ++unresolved; } if (cel) unlock_cache(cel); return unresolved; }
// performs tasks needed before an item can be procssed by execute(): // checks work and cache for existing results, validates or purges them, // reserves space if necessary, locks the cache entry (must be released with postprocess_output_path) output_file * preprocess_output_path (const char * id, artifacts_spec * spec, boolean use_work, boolean use_cache, artifacts_spec * prev_spec) { int ret = OK; output_file * o = calloc (1, sizeof (output_file)); // all pointers are NULL, all booleans are FALSE if (o==NULL) { logprintfl (EUCAERROR, "out of memory in preprocess_output_path()\n"); return NULL; } o->do_work = use_work; o->do_cache = use_cache; safe_strncpy (o->id, id, sizeof (o->id)); // is there a valid work copy already? o->work_copy = find_disk_item (id, FALSE); if (o->work_copy!=NULL) { // there is a copy if (verify_disk_item (o->work_copy, spec)) { // does it match the spec? if (prev_spec!=NULL && verify_disk_item (o->work_copy, prev_spec)==OK) { // does it match previous stage's spec? logprintfl (EUCAINFO, "found previous stage's work copy of image '%s'\n", id); if (add_summ_disk_item (o->work_copy, spec)!=OK) { // update the spec logprintfl (EUCAERROR, "error: failed to update summary of work copy of '%s'\n", id); ret = ERROR; goto cleanup; } else { o->predecessor = TRUE; o->in_work = TRUE; } } else { delete_disk_item (o->work_copy); // no => delete it free_disk_item (o->work_copy); o->work_copy = NULL; logprintfl (EUCAINFO, "purged a stale work copy of image '%s'\n", id); } } else { o->in_work = TRUE; logprintfl (EUCAINFO, "found a valid work copy of image '%s'\n", id); } } if (o->do_work && !o->in_work) { // no valid work copy => reserve space o->work_copy = alloc_disk_item (id, 0, spec->size, FALSE); if (o->work_copy==NULL) { ret = ERROR; goto cleanup; } if (reserve_disk_item (o->work_copy)!=OK) { // reserve room for the object logprintfl (EUCAERROR, "error: failed to allocate work space for '%s'\n", id); ret = ERROR; goto cleanup; } if (add_summ_disk_item (o->work_copy, spec)!=OK) { logprintfl (EUCAERROR, "error: failed to add summary to work copy of '%s'\n", id); ret = ERROR; goto cleanup; } } // if caching, is there a valid cached copy? if (o->do_cache) { lock_cache (); o->cache_copy = find_disk_item (id, TRUE); if (o->cache_copy!=NULL) { // there is a copy with this id in the cache? lock_disk_item (o->cache_copy); // NOTE: may be unlocked by the _delete if (verify_disk_item (o->cache_copy, spec)) { // does it match the spec? if (prev_spec!=NULL && o->work_copy != NULL && verify_disk_item (o->work_copy, prev_spec)==OK) { // does it match previous stage's spec? logprintfl (EUCAINFO, "found previous stage's cache copy of image '%s'\n", id); if (add_summ_disk_item (o->cache_copy, spec)!=OK) { // update the spec logprintfl (EUCAERROR, "error: failed to update summary of cache copy of '%s'\n", id); delete_disk_item (o->cache_copy); free_disk_item (o->cache_copy); o->cache_copy = NULL; } else { o->predecessor = TRUE; o->in_cache = TRUE; } } else { delete_disk_item (o->cache_copy); // no => purge it free_disk_item (o->cache_copy); o->cache_copy = NULL; logprintfl (EUCAINFO, "purged a stale cache copy of image '%s'\n", id); } } else { o->in_cache = TRUE; logprintfl (EUCAINFO, "found a valid cache copy of image '%s'\n", id); } } if (!o->in_cache) { // not in cache => reserve space, purging LRU items if necessary o->cache_copy = alloc_disk_item (id, 0, spec->size, TRUE); if (o->cache_copy!=NULL) { lock_disk_item (o->cache_copy); if (reserve_disk_item (o->cache_copy)==OK) { // there is room in the cache if (add_summ_disk_item (o->cache_copy, spec)!=OK) { logprintfl (EUCAERROR, "error: failed to add summary to cache copy of '%s'\n", id); delete_disk_item (o->cache_copy); free_disk_item (o->cache_copy); o->cache_copy = NULL; } else { o->to_cache = TRUE; } } else { logprintfl (EUCAERROR, "warning: no room in cache for image '%s'\n", id); } } } unlock_cache (); } char * result_path = NULL; if (! (o->in_work || o->in_cache) || o->predecessor) { // no local copy, so execute() will have to create it // => decide where the result should go: work or cache if (o->do_work) { result_path = get_disk_item_path (o->work_copy); o->in_work = TRUE; } else if (o->to_cache) { result_path = get_disk_item_path (o->cache_copy); o->in_cache = TRUE; } else { logprintfl (EUCAERROR, "error: no work or cache space for downloading '%s'\n", id); ret = ERROR; } } if (result_path) { safe_strncpy (o->path, result_path, sizeof (o->path)); } cleanup: // in case of error: delete disk state, unlock cache item // TODO: be more selective? invalidate cache? if (ret==ERROR) { if (o->work_copy!=NULL) { delete_disk_item (o->work_copy); free_disk_item (o->work_copy); } if (o->do_cache && o->cache_copy!=NULL) { unlock_disk_item (o->cache_copy); } free (o); o = NULL; } return o; }
/* * Insert cache into the list */ static FcBool FcCacheInsert (FcCache *cache, struct stat *cache_stat) { FcCacheSkip **update[FC_CACHE_MAX_LEVEL]; FcCacheSkip *s, **next; int i, level; lock_cache (); /* * Find links along each chain */ next = fcCacheChains; for (i = fcCacheMaxLevel; --i >= 0; ) { for (; (s = next[i]); next = s->next) if (s->cache > cache) break; update[i] = &next[i]; } /* * Create new list element */ level = random_level (); if (level > fcCacheMaxLevel) { level = fcCacheMaxLevel + 1; update[fcCacheMaxLevel] = &fcCacheChains[fcCacheMaxLevel]; fcCacheMaxLevel = level; } s = malloc (sizeof (FcCacheSkip) + (level - 1) * sizeof (FcCacheSkip *)); if (!s) return FcFalse; s->cache = cache; s->size = cache->size; FcRefInit (&s->ref, 1); if (cache_stat) { s->cache_dev = cache_stat->st_dev; s->cache_ino = cache_stat->st_ino; s->cache_mtime = cache_stat->st_mtime; #ifdef HAVE_STRUCT_STAT_ST_MTIM s->cache_mtime_nano = cache_stat->st_mtim.tv_nsec; #else s->cache_mtime_nano = 0; #endif } else { s->cache_dev = 0; s->cache_ino = 0; s->cache_mtime = 0; s->cache_mtime_nano = 0; } /* * Insert into all fcCacheChains */ for (i = 0; i < level; i++) { s->next[i] = *update[i]; *update[i] = s; } unlock_cache (); return FcTrue; }