Example #1
0
/*
 * 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;
}
Example #3
0
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;
}
Example #4
0
static sapgss_OID
cache_lookup(gss_OID loc)
{
    sapgss_OID o;

    lock_cache();
    o = cache_lookup_locked(loc);
    unlock_cache();
    return o;
}
Example #5
0
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;
}
Example #7
0
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 ();
}
Example #9
0
/*==========================================================
 * 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);
}
Example #10
0
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);
}
Example #11
0
/*===================================
 * 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;
}
Example #12
0
/*=====================================
 * 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;
}
Example #13
0
/*=====================================
 * 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;
}
Example #14
0
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;
}
Example #15
0
/*==========================================================
 * 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;
}
Example #16
0
// 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;
}