示例#1
0
文件: bif_proc.c 项目: bkearns/ling
term_t cbif_unlink1(proc_t *proc, term_t *regs)
{
	term_t PidOid = regs[0];

	if (!is_short_pid(PidOid) && !is_short_oid(PidOid))
		badarg(PidOid);

	proc_t *peer_proc = 0;
	outlet_t *peer_outlet = 0;

	if (is_short_pid(PidOid))
		peer_proc = scheduler_lookup(PidOid);
	else
		peer_outlet = outlet_lookup(PidOid);

	inter_links_t *peer_links = 0;
	if (peer_proc != 0)
		peer_links = &peer_proc->links;
	else if (peer_outlet != 0)
		peer_links = &peer_outlet->links;

	if (peer_links != 0)
	{
		if (are_inter_linked(&proc->links, PidOid))
		{
			inter_link_break(&proc->links, PidOid);
			inter_link_break(peer_links, proc->pid);
		}
	}

	return A_TRUE;
}
示例#2
0
// This function "zips" all ready items from:
// `ol->accepting` queue (requests from the VM)
// and `ol->accepted` queue (requests from network)
static void bake_all_accepted(outlet_t *ol)
{
	// bake_one_accepted() may close the outlet, so save oid:
	term_t saved_oid = ol->oid;

	// exhaust either ol->accepting or ol->accepted :
	while (ol->accepting != 0 && ol->accepted != 0)
	{
		acc_pend_t *pend = pop_from_ring(&ol->accepting);

		if (pend->timeout_set)
			tcp_accept_untimeout(pend);

		term_t reply_to = pend->reply_to;

		reuse_pending(&ol->free_pends, pend);

		proc_t *cont_proc = scheduler_lookup(reply_to);
		if (cont_proc == 0)
			continue;

		// this will pop a `pend` from ol->accepted
		bake_one_accepted(ol, cont_proc);

		if (outlet_lookup(saved_oid) == 0)
			break;
	}
}
示例#3
0
文件: bif_proc.c 项目: bkearns/ling
term_t cbif_link1(proc_t *proc, term_t *regs)
{
	term_t PidOid = regs[0];

	if (!is_short_pid(PidOid) && !is_short_oid(PidOid))
		badarg(PidOid);

	if (PidOid == proc->pid)
		return A_TRUE;

	proc_t *peer_proc = 0;
	outlet_t *peer_outlet = 0;

	if (is_short_pid(PidOid))
		peer_proc = scheduler_lookup(PidOid);
	else
		peer_outlet = outlet_lookup(PidOid);

	inter_links_t *peer_links = 0;
	if (peer_proc != 0)
		peer_links = &peer_proc->links;
	else if (peer_outlet != 0)
		peer_links = &peer_outlet->links;

	if (peer_proc == 0 && peer_outlet == 0)
	{
		if (proc->trap_exit == A_TRUE)
		{
			int x = scheduler_signal_exit_N(proc, proc->pid, A_NOPROC);	// does not destroy the proc
			if (x < 0)
				fail(A_NOT_LINKED);

			return A_TRUE;
		}
		else
			fail(A_NOPROC);
	}
	else
	{
		if (!are_inter_linked(&proc->links, PidOid))
		{
			int x = inter_link_establish_N(&proc->links, PidOid);
			if (x < 0)
				fail(A_NOT_LINKED);
			x = inter_link_establish_N(peer_links, proc->pid);
			if (x < 0)
			{
				inter_link_break(&proc->links, PidOid);
				fail(A_NOT_LINKED);
			}
		}
		return A_TRUE;
	}
}