Ejemplo n.º 1
0
term_t bif_embedded_module1(term_t Mod, process_t *ctx)
{
	xmod_bin_t *mp, *me;
	cstr_t *s;
	
	if (!is_atom(Mod))
		return A_BADARG;

	s = atoms_get(proc_atoms(ctx), index(Mod));
	
	mp = (xmod_bin_t *)module_bins->elts;
	me = mp + module_bins->nelts;
	while (mp < me)
	{
		if (scomp(mp->name, s))
		{
			term_t bin = make_binary(intnum(mp->size), mp->data, proc_gc_pool(ctx));
			result(make_tuple3(A_OK, bin, bool(mp->is_preloaded), proc_gc_pool(ctx)));
			return AI_OK;
		}
		mp++;
	}
	result(A_FALSE);
	return AI_OK;
}
Ejemplo n.º 2
0
static int so_atom_add(session_opt_t *so, const char *id, char *buf, 
    size_t size, void *arg)
{
    atom_t *atom = NULL, *old = NULL;
    size_t new_size, old_found = 0;

    dbg_err_if (so == NULL);
    dbg_err_if (id == NULL);
    dbg_err_if (buf == NULL);

    /* get the old atom associated to this id */
    if(!atoms_get(so->atoms, id, &old))
        old_found = 1;

    /* delete the oldest session if there are already max_count sessions */
    if(so->max_count && atoms_count(so->atoms) - old_found >= so->max_count)
        dbg_err_if(session_delete_oldest(so));

    /* delete the oldest session(s) if we are using already mem_limit bytes */
    if(so->mem_limit)
    {
        warn_err_ifm(size > so->mem_limit, 
            "session size is bigger the memory.limit, save aborted...");
        for(;;)
        {
            /* new_size = size of all atoms + size of the atom we're going to
               add - the size of the atom (if found) we're going to remove */
            new_size = atoms_size(so->atoms) + size - (old ? old->size : 0);
            if(atoms_count(so->atoms) && new_size > so->mem_limit)
                dbg_err_if(session_delete_oldest(so));
            else
                break;
        }
    }

    /* create a new atom */
    dbg_err_if(atom_create(id, buf, size, arg, &atom));

    /* add it to the list */
    dbg_err_if(atoms_add(so->atoms, atom));

    /* remove the old atom associated to this id */
    if(old)
    {
        dbg_err_if(atoms_remove(so->atoms, old));
        atom_free(old);
    }

    return 0;
err:
    if(atom)
        atom_free(atom);
    return ~0;
}
Ejemplo n.º 3
0
static int session_mem_load(session_t *ss)
{
    enum { BUFSZ = 4096 };
    atom_t *atom;
    char buf[BUFSZ];
    size_t size;
    enc_ses_mem_t *esm;
    ppc_t *ppc;
    unsigned char cmd;

    dbg_err_if (ss == NULL);
    nop_err_if (ss->filename == NULL || strlen(ss->filename) == 0);

    /* in fork and iterative model we can get the session from the current
       address space, in prefork we must ask the parent for a fresh copy of 
       the session */
    if(ctx->backend && ctx->backend->model == SERVER_MODEL_PREFORK)
    {   /* get the session data through ppc */
        ppc = server_get_ppc(ctx->server);
        dbg_err_if(ppc == NULL);

        /* send a get request */
        dbg_err_if(ppc_write(ppc, ctx->pipc, PPC_CMD_MSES_GET, ss->filename, 
            strlen(ss->filename) + 1) < 0);

        /* get the response from the parent */
        dbg_err_if((size = ppc_read(ppc, ctx->pipc, &cmd, buf, BUFSZ)) <= 0);

        nop_err_if(cmd != PPC_CMD_RESPONSE_OK);

        /* load session from esm */
        esm = (enc_ses_mem_t*)buf;
        ss->mtime = esm->mtime;
        dbg_err_if(session_prv_load_from_buf(ss, esm->data, esm->size));

    } else {
        /* find the file into the atom list */
        if(atoms_get(ss->so->atoms, ss->filename, &atom))
            return ~0; /* not found */

        /* copy stored mtime */
        ss->mtime = (time_t)atom->arg;

        /* load session from atom->data */
        dbg_err_if(session_prv_load_from_buf(ss, atom->data, atom->size));
    }

    return 0;
err:
    return ~0;
}
Ejemplo n.º 4
0
/* [parent] get session data */
static int session_cmd_get(ppc_t *ppc, int fd, unsigned char cmd, char *data, 
    size_t size, void *vso)
{
    enum { BUFSZ = 4096 };
    session_opt_t *so = vso;
    enc_ses_mem_t *esm = NULL;
    atom_t *atom = NULL;
    char buf[BUFSZ];
    size_t esm_size;

    u_unused_args(cmd, size);

    dbg_err_if (ppc == NULL);
    dbg_err_if (vso == NULL);
    dbg_err_if (data == NULL);
    dbg_err_if (strlen(data) > SESSION_FILENAME_MAX_LENGTH);

    /* find the atom whose name is stored into 'data' buffer */
    nop_err_if(atoms_get(so->atoms, data, &atom));

    /* if the buffer on the stack is big enough use it, otherwise alloc a 
       bigger one on the heap */
    if((esm_size = sizeof(enc_ses_mem_t) + atom->size) > BUFSZ)
    {
        esm = u_malloc(1 + esm_size);
        dbg_err_if(esm == NULL);
    } else
        esm = (enc_ses_mem_t*)buf;
        
    /* fill the enc_ses_mem_t struct */
    esm->mtime = (time_t)atom->arg;
    u_strlcpy(esm->filename, data, sizeof esm->filename);
    esm->size = atom->size;
    memcpy(esm->data, atom->data, atom->size);

    dbg_err_if(ppc_write(ppc, fd, PPC_CMD_RESPONSE_OK, (char*)esm,
        esm_size) <= 0);

    if(esm && esm != (void*)buf)
        U_FREE(esm);

    return 0;
err:
    if(ppc)
        ppc_write(ppc, fd, PPC_CMD_RESPONSE_ERROR, (char *)"", 1);
    if(esm && esm != (void *)buf)
        U_FREE(esm);
    return ~0;
}
Ejemplo n.º 5
0
static int so_atom_remove(session_opt_t *so, const char *id)
{
    atom_t *atom = NULL;

    dbg_err_if (so == NULL);
    dbg_err_if (id == NULL);

    /* find the atom bound to this session */
    if(atoms_get(so->atoms, id, &atom))
        return 0;

    /* remove it from the list */
    dbg_err_if(atoms_remove(so->atoms, atom));

    atom_free(atom);

    return 0;
err:
    return ~0;
}
Ejemplo n.º 6
0
int is_term_smaller(term_t a, term_t b)
{
	if (a == b)
		return 0;

	if (are_both_immed(a, b))
	{
		if (are_both_int(a, b))
			return int_value(a) < int_value(b);

		if (is_int(a))	// !is_int(b)
			return 1;

		if (is_nil(a))	// !is_nil(b)
			return 0;
		if (is_nil(b))	// !is_nil(a)
			return 1;

		if (is_atom(a))
		{
			if (is_int(b))
				return 0;
			else if (is_atom(b))
			{
				uint8_t *print1 = atoms_get(atom_index(a));
				uint8_t *print2 = atoms_get(atom_index(b));
				int short_len = (print1[0] < print2[0])
					? print1[0]
					: print2[0];
				int d = memcmp(print1+1, print2+1, short_len);
				if (d == 0)
					return print1[0] < print2[0];
				return d < 0;
			}
			else
				return 1;
		}
		else if (is_short_oid(a))
		{
			if (is_int(b) || is_atom(b))
				return 0;
			else if (is_short_oid(b))
				return short_oid_id(a) < short_oid_id(b);
			else
				return 1;
		}
		else if (is_short_pid(a))
		{
			if (is_int(b) || is_atom(b) || is_short_oid(b))
				return 0;
			else
			{
				assert(is_short_pid(b));
				return short_pid_id(a) < short_pid_id(b);
			}
		}
	}

	//TODO: comparison of bignum and float: docs mention the
	// number 9007199254740992.0 and a loss of transitivity
	
	if (!is_immed(a) && !is_immed(b) &&
				primary_tag(a) == primary_tag(b))
	{
		if (is_cons(a))
			return is_term_smaller_1(a, b);
		else if (is_tuple(a))
			return is_term_smaller_2(a, b);
		else
		{
			assert(is_boxed(a) && is_boxed(b));
			uint32_t *adata = peel_boxed(a);
			uint32_t *bdata = peel_boxed(b);
			if (boxed_tag(adata) == boxed_tag(bdata) ||
					(is_binary(adata) && is_binary(bdata)) ||
					(is_bignum(adata) && is_bignum(bdata)))
			{
				switch(boxed_tag(adata))
				{
				case SUBTAG_POS_BIGNUM:
				case SUBTAG_NEG_BIGNUM:
					return bignum_compare((bignum_t *)adata,
										  (bignum_t *)bdata) < 0;
				case SUBTAG_FUN:
					return fun_compare((t_fun_t *)adata,
									   (t_fun_t *)bdata) < 0;
				case SUBTAG_EXPORT:
					return export_compare((t_export_t *)adata,
									   	  (t_export_t *)bdata) < 0;

				case SUBTAG_PID:
					return pid_compare((t_long_pid_t *)adata,
									   (t_long_pid_t *)bdata) < 0;

				case SUBTAG_OID:
					return oid_compare((t_long_oid_t *)adata,
									   (t_long_oid_t *)bdata) < 0;

				case SUBTAG_REF:
					return ref_compare((t_long_ref_t *)adata,
									   (t_long_ref_t *)bdata) < 0;

				case SUBTAG_PROC_BIN:
				case SUBTAG_HEAP_BIN:
				case SUBTAG_MATCH_CTX:
				case SUBTAG_SUB_BIN:
					return is_term_smaller_3(adata, bdata);

				default:
					assert(boxed_tag(adata) == SUBTAG_FLOAT);
					return float_value(adata) < float_value(bdata);
				}
			}
		}
	}

	// Number comparison with (mandatory) coercion
	//
	int use_float = (is_boxed(a) && boxed_tag(peel_boxed(a)) == SUBTAG_FLOAT) ||
					(is_boxed(b) && boxed_tag(peel_boxed(b)) == SUBTAG_FLOAT);

	if (use_float)
	{
		if (is_int(a))	// b is always float
			return (double)int_value(a) < float_value(peel_boxed(b));
		else if (is_boxed(a))
		{
			uint32_t *adata = peel_boxed(a);
			if (is_bignum(adata))	// b is always float
				return bignum_to_double((bignum_t *)adata) < float_value(peel_boxed(b));

			if (boxed_tag(adata) == SUBTAG_FLOAT)
			{
				if (is_int(b))
					return float_value(adata) < (double)int_value(b);
				if (is_boxed(b))
				{
					uint32_t *bdata = peel_boxed(b);
					if (is_bignum(bdata))
						return float_value(adata) < bignum_to_double((bignum_t *)bdata);
				}
			}
		}
	}
	else	// use integer
	{
		if (is_int(a))
		{
			if (is_boxed(b))
			{
				uint32_t *bdata = peel_boxed(b);
				if (is_bignum(bdata))
				{
					bignum_t *bbn = (bignum_t *)bdata;
					return !bignum_is_neg(bbn);
				}
				assert(boxed_tag(bdata) != SUBTAG_FLOAT);
			}
		}
		else if (is_boxed(a))
		{
			uint32_t *adata = peel_boxed(a);
			if (is_bignum(adata))
			{
				bignum_t *abn = (bignum_t *)adata;
				if (is_int(b))
					return bignum_is_neg(abn);

				if (is_boxed(b))
				{
					uint32_t *bdata = peel_boxed(b);
					if (is_bignum(bdata))
						return bignum_compare(abn, (bignum_t *)bdata);
					assert(boxed_tag(bdata) != SUBTAG_FLOAT);
				}
			}

			assert(boxed_tag(adata) != SUBTAG_FLOAT);
		}
	}

	// a and b are quaranteed to have different types
	// 
	
	return term_order(a) < term_order(b);
}