Exemplo n.º 1
0
static Handle reuse_existing_handle(uintptr_t key, H_Type type, size_t flags)
{
	if(flags & RES_NO_CACHE)
		return 0;

	// object of specified key and type doesn't exist yet
	Handle h = h_find(type, key);
	if(h <= 0)
		return 0;

	HDATA* hd;
	RETURN_STATUS_IF_ERR(h_data_tag_type(h, type, hd));	// h_find means this won't fail

	hd->refs += 1;

	// we are reactivating a closed but cached handle.
	// need to generate a new tag so that copies of the
	// previous handle can no longer access the resource.
	// (we don't need to reset the tag in h_free, because
	// use before this fails due to refs > 0 check in h_user_data).
	if(hd->refs == 1)
	{
		const Tag tag = gen_tag();
		h = handle(h_idx(h), tag);	// can't fail
		hd->h = h;
	}

	return h;
}
Exemplo n.º 2
0
static Handle alloc_new_handle(H_Type type, const PIVFS& vfs, const VfsPath& pathname, uintptr_t key, size_t flags, va_list* init_args)
{
	HDATA* hd = (HDATA*)pool_alloc(&hpool, 0);
	if(!hd)
		WARN_RETURN(ERR::NO_MEM);
	new(&hd->pathname) VfsPath;

	ssize_t idx = h_idx_from_data(hd);
	RETURN_STATUS_IF_ERR(idx);

	// (don't want to do this before the add-reference exit,
	// so as not to waste tags for often allocated handles.)
	const Tag tag = gen_tag();
	Handle h = handle(idx, tag);	// can't fail.

	hd->h = h;
	hd->key  = key;
	hd->type = type;
	hd->refs = 1;
	if(!(flags & RES_NO_CACHE))
		hd->keep_open = 1;
	if(flags & RES_DISALLOW_RELOAD)
		hd->disallow_reload = 1;
	hd->unique = (flags & RES_UNIQUE) != 0;
	hd->pathname = pathname;

	if(key && !hd->unique)
		key_add(key, h);

	Status err = call_init_and_reload(h, type, hd, vfs, pathname, init_args);
	if(err < 0)
		goto fail;

	return h;

fail:
	// reload failed; free the handle
	hd->keep_open = 0;	// disallow caching (since contents are invalid)
	(void)h_free(h, type);	// (h_free already does WARN_IF_ERR)

	// note: since some uses will always fail (e.g. loading sounds if
	// g_Quickstart), do not complain here.
	return (Handle)err;
}
Exemplo n.º 3
0
//==========================================================================================================
// Get the value for a variable that appear in the script in brackets (like [call_id]). Some are static to
// the test (received from MServer), some generated, some stored from previous messages.
//==========================================================================================================
string ScriptReader::get_value(string var, int call_number, bool try_as_last)
{
    smatch match;
    
    if(!regex_match(var, match, var_regex))
    {
        throw string("Wrong format for var in ScriptReader::get_value(): " + var);
    }
    
    // var_regex:   "(last_)?(((cseq)\\+(\\d+))|([-\\w]+))(:value)?"
    // submatches:   1       234        5       6         7
    bool is_last = (match[1].length() > 0);
    bool just_value = (match[7].length() >  0);
    int add_to_cseq = 0;
    string name = match[2];

    if(match[3].length() > 0)
    {
        name = match[4];
        add_to_cseq = stoi(match[5]);
    }
    
    if(is_last || (try_as_last && (SipMessage::is_message_var(name) || SipParser::inst().match(HEADER_NAME, name))))
    {
        string result = get_last_value(name, call_number, just_value);
        
        if(name == CSEQ)
        {
            return to_string(stoi(result) + add_to_cseq);
        }
        
        return result;
    }
    
    if(name == BRANCH)
    {
        return gen_branch();
    }
    
    CallIDKind cid_kind = string_to_call_id_kind(name);
    
    if(cid_kind != NONE)
    {
        return gen_call_id(cid_kind);
    }
    
    if(name == TAG)
    {
        return gen_tag();
    }
    
    if(vars.count(name) != 0)
    {
        return vars[name];
    }
    
    if(static_vars.count(name) != 0)
    {
        return static_vars.at(name);
    }
    
    return MServer::inst.get_value(name);
}