Esempio n. 1
0
BIF_RETTYPE open_port_2(BIF_ALIST_2)
{
    Port *port;
    Eterm port_id;
    char *str;
    int err_type, err_num;

    port = open_port(BIF_P, BIF_ARG_1, BIF_ARG_2, &err_type, &err_num);
    if (!port) {
	if (err_type == -3) {
	    ASSERT(err_num == BADARG || err_num == SYSTEM_LIMIT);
	    BIF_ERROR(BIF_P, err_num);
	} else if (err_type == -2) {
	    str = erl_errno_id(err_num);
	} else {
	    str = "einval";
	}
	BIF_P->fvalue = erts_atom_put((byte *) str, strlen(str), ERTS_ATOM_ENC_LATIN1, 1);
	BIF_ERROR(BIF_P, EXC_ERROR);
    }

    erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_LINK);

    port_id = port->common.id;
    erts_add_link(&ERTS_P_LINKS(port), LINK_PID, BIF_P->common.id);
    erts_add_link(&ERTS_P_LINKS(BIF_P), LINK_PID, port_id);

    erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_LINK);

    erts_port_release(port);

    BIF_RET(port_id);
}
Esempio n. 2
0
BIF_RETTYPE open_port_2(BIF_ALIST_2)
{
    int port_num;
    Eterm port_val;
    char *str;
    int err_num;

    if ((port_num = open_port(BIF_P, BIF_ARG_1, BIF_ARG_2, &err_num)) < 0) {
	if (port_num == -3) {
	    ASSERT(err_num == BADARG || err_num == SYSTEM_LIMIT);
	    BIF_ERROR(BIF_P, err_num);
	} else if (port_num == -2) {
	    str = erl_errno_id(err_num);
	} else {
	    str = "einval";
	}
	BIF_P->fvalue = am_atom_put(str, strlen(str));
	BIF_ERROR(BIF_P, EXC_ERROR);
    }

    erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_LINK);

    port_val = erts_port[port_num].id;
    erts_add_link(&(erts_port[port_num].nlinks), LINK_PID, BIF_P->id);
    erts_add_link(&(BIF_P->nlinks), LINK_PID, port_val);

    erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_LINK);

    erts_port_release(&erts_port[port_num]);

    BIF_RET(port_val);
}
Esempio n. 3
0
BIF_RETTYPE port_connect_2(BIF_ALIST_2)
{
    Port* prt;
    Process* rp;
    Eterm pid = BIF_ARG_2;

    if (is_not_internal_pid(pid)) {
    error:
	BIF_ERROR(BIF_P, BADARG);
    }
    prt = id_or_name2port(BIF_P, BIF_ARG_1);
    if (!prt) {
	goto error;
    }

    rp = erts_pid2proc(BIF_P, ERTS_PROC_LOCK_MAIN,
		       pid, ERTS_PROC_LOCK_LINK);
    if (!rp) {
	erts_smp_port_unlock(prt);
	ERTS_SMP_ASSERT_IS_NOT_EXITING(BIF_P);
	goto error;
    }

    erts_add_link(&(rp->nlinks), LINK_PID, prt->id);
    erts_add_link(&(prt->nlinks), LINK_PID, pid);

    erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_LINK);

    prt->connected = pid; /* internal pid */
    erts_smp_port_unlock(prt);
#ifdef USE_VM_PROBES
    if (DTRACE_ENABLED(port_connect)) {
        DTRACE_CHARBUF(process_str, DTRACE_TERM_BUF_SIZE);
        DTRACE_CHARBUF(port_str, DTRACE_TERM_BUF_SIZE);
        DTRACE_CHARBUF(newprocess_str, DTRACE_TERM_BUF_SIZE);

        dtrace_pid_str(prt->connected, process_str);
        erts_snprintf(port_str, sizeof(port_str), "%T", prt->id);
        dtrace_proc_str(rp, newprocess_str);
        DTRACE4(port_connect, process_str, port_str, prt->name, newprocess_str);
    }
#endif
    BIF_RET(am_true);
}
Esempio n. 4
0
BIF_RETTYPE erts_internal_open_port_2(BIF_ALIST_2)
{
    Port *port;
    Eterm res;
    char *str;
    int err_type, err_num;

    port = open_port(BIF_P, BIF_ARG_1, BIF_ARG_2, &err_type, &err_num);
    if (!port) {
	if (err_type == -3) {
	    ASSERT(err_num == BADARG || err_num == SYSTEM_LIMIT);
	    if (err_num == BADARG)
                res = am_badarg;
            else if (err_num == SYSTEM_LIMIT)
                res = am_system_limit;
            else
                /* this is only here to silence gcc, it should not happen */
                BIF_ERROR(BIF_P, EXC_INTERNAL_ERROR);
	} else if (err_type == -2) {
	    str = erl_errno_id(err_num);
            res = erts_atom_put((byte *) str, strlen(str), ERTS_ATOM_ENC_LATIN1, 1);
	} else {
	    res = am_einval;
	}
        BIF_RET(res);
    }

    if (port->drv_ptr->flags & ERL_DRV_FLAG_USE_INIT_ACK) {

        /* Copied from erl_port_task.c */
        port->async_open_port = erts_alloc(ERTS_ALC_T_PRTSD,
                                           sizeof(*port->async_open_port));
        erts_make_ref_in_array(port->async_open_port->ref);
        port->async_open_port->to = BIF_P->common.id;

        erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCKS_MSG_RECEIVE | ERTS_PROC_LOCK_LINK);
        if (ERTS_PROC_PENDING_EXIT(BIF_P)) {
	    /* need to exit caller instead */
	    erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCKS_MSG_RECEIVE | ERTS_PROC_LOCK_LINK);
	    KILL_CATCHES(BIF_P);
	    BIF_P->freason = EXC_EXIT;
            erts_port_release(port);
            BIF_RET(am_badarg);
	}

	ERTS_SMP_MSGQ_MV_INQ2PRIVQ(BIF_P);
	BIF_P->msg.save = BIF_P->msg.last;

	erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCKS_MSG_RECEIVE);

        res = erts_proc_store_ref(BIF_P, port->async_open_port->ref);
    } else {
        res = port->common.id;
        erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_LINK);
    }

    erts_add_link(&ERTS_P_LINKS(port), LINK_PID, BIF_P->common.id);
    erts_add_link(&ERTS_P_LINKS(BIF_P), LINK_PID, port->common.id);

    if (IS_TRACED_FL(BIF_P, F_TRACE_PROCS))
        trace_proc(BIF_P, ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_LINK, BIF_P,
                   am_link, port->common.id);

    erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_LINK);

    erts_port_release(port);

    BIF_RET(res);
}
Esempio n. 5
0
Eterm erl_create_process(ErlProcess* parent, Eterm module, Eterm function, Eterm args, ErlSpawnOpts* opts) {
	int i;
	uint16_t last_proc;
	for(i=0; i<MAX_PROCESSES; i++) {
		if(proc_tab[i].active == 0) {
			last_proc = i;
			break;
		}
	}


	if(last_proc == MAX_PROCESSES) {
		erl_exit("maximum number of processes reached!");
		//@todo return NIL;
	}

	ErlProcess* p = (ErlProcess*)&proc_tab[last_proc];
	Eterm pid = pix2pid(last_proc);
	p->parent = parent;
	p->id = pid;

	p->timer.active = 0;
	p->timer.arg = NULL;
	p->timer.cancel = NULL;
	p->timer.count = 0;
	p->timer.next = NULL;
	p->timer.prev = NULL;
	p->timer.slot = 0;
	p->timer.timeout = NULL;

	//@todo throw an error if exported was not found
	p->arity = 3;
	p->arg_reg = p->def_arg_reg;
	p->max_arg_reg = sizeof(p->def_arg_reg)/sizeof(p->def_arg_reg[0]);
	for(i=0; i<p->max_arg_reg; i++) {
		p->def_arg_reg[i] = 0;
	}
	p->fcalls = REDUCTIONS;
	p->active = 1;

	p->flags = 0;

	p->msg.len = 0;
	p->msg.first = NULL;
	p->msg.last = &p->msg.first;
	p->msg.save = &p->msg.first;
	p->msg.saved_last = NULL;

	p->links = NULL;
	if(opts && (opts->flags & SPO_LINK)) {
		erts_add_link(&p->links, parent->id);
		erts_add_link(&parent->links, p->id);
	}

	// initialize heap
	unsigned int arg_size = size_object(args);
	unsigned int heap_need = arg_size;
	unsigned int sz = erts_next_heap_size(heap_need);

	p->heap = (Eterm*)pvPortMalloc(sz * sizeof(Eterm));
	p->stop = p->hend = p->heap + sz;
	p->htop = p->heap;
	p->heap_sz = sz;

	p->i = (BeamInstr*)(beam_apply);
	p->cp = (BeamInstr*)(beam_apply + 1);
	p->saved_i = (BeamInstr*)(beam_apply + 2);
	p->arg_reg[0] = module;
	p->arg_reg[1] = function;
	p->arg_reg[2] = copy_struct(args, arg_size, &p->htop);

	//start process inside the FreeRTOS scheduler
	vTaskResume(*(p->handle));

	return pid;
}